[Django实战] 第9篇

本章通过实现一个用户提交任务请求的页面,讲述表单、视图、模型、模板间的交互。

首先,我们需要定义一个表单(forms.py)

class CreatetaskForm(forms.Form):
    creater = forms.CharField(
        label=u"创建者",
        widget=BootstrapUneditableInput()
    )
    manager = forms.ModelChoiceField(
        queryset=Manager.objects.all(),
        required=True,
        label=u"项目负责人",
        error_messages={'required': u'必选项'},
    )  
    databases = forms.ModelMultipleChoiceField(
        queryset=Database.objects.order_by('id'),
        required=True,
        label=u"数据库",
        error_messages={'required': u'至少选择一个'},
        widget=forms.CheckboxSelectMultiple,
    )    
    sql = forms.CharField(
        required=False,
        label=u"执行SQL",
        widget=forms.Textarea(
            attrs={
                'placeholder':"请在表名前加上schema,如hospital要写成p95169.hospital",
                'rows':5,
                'style':"100%",
            }
        ),
    )
    desc = forms.CharField(
        required=False,
        label=u"描述",
        widget=forms.Textarea(
            attrs={
                'placeholder':"如果不是执行SQL(如数据的导入导出等),一定要在描述里说清楚",
                'rows':5,
                'style':"100%",
            }
        ),
    ) 
    attachment = forms.FileField(
        required=False,
        label=u"附件",
        help_text=u"如果SQL文本过长,超过2000个字符,请上传附件"
    )
    def clean(self):
        if not self.is_valid():
            raise forms.ValidationError(u"以下红色标记部分为必选项")
        elif self.cleaned_data['sql'] == u'' and self.cleaned_data['desc'] == u'' :
            raise forms.ValidationError(u"如果执行SQL为空,描述为必填项")
        else:
            cleaned_data = super(CreatetaskForm, self).clean() 
        return cleaned_data

该表单包含一个多选框和附件上传,然后我们创建一个视图来实例化该表单:

import datetime
@login_required
def createtask(request):
    if request.method == 'GET':
        form = CreatetaskForm(initial={
        'creater':request.user.last_name + request.user.first_name,
        })
        return render_to_response('createtask.html', RequestContext(request, {'form': form,}))
    else:
        form = CreatetaskForm(request.POST,request.FILES)
        if form.is_valid():
            username = request.user.username
            t = Task.objects.create(
                creater = User.objects.get(username=username),
                manager = form.cleaned_data['manager'],
                dba = Dba.objects.get(id=1),
                state = State.objects.get(statename='Open'),
                sql = form.cleaned_data['sql'],
                desc = form.cleaned_data['desc'],
                createdtime = datetime.datetime.now(),
                lastupdatedtime = datetime.datetime.now(),
                attachment = form.cleaned_data['attachment'],
            )
            databaselist = form.cleaned_data['databases']
            for db in databaselist:
                t.databases.add(db)
            t.save()
            return render_to_response('base.html', RequestContext(request,{'createtask_success':True,}))
        else:
            return render_to_response('createtask.html', RequestContext(request, {'form': form,}))

该视图的业务逻辑是:

1)当用户提交表单后,验证表单的正确性

2)如果表单填写不正确,显示错误提示信息

3)如果表单填写正确,在数据库表Task里插入一条信息

其中,模型createtask.html的定义如下:

{% extends "base.html" %}

{% load bootstrap_toolkit %}

{% block extra_head %}
    {{ form.media }}
{% endblock %}

{% block content %}

    <h1>创建任务</h1>
    
    <div class="well">    
    <form enctype="multipart/form-data" class="form-horizontal" action="" method="post">
        {% csrf_token %}
        {{ form|as_bootstrap:"horizontal" }}
        <p class="form-actions">
                <input type="submit" value="提交" class="btn btn-primary">
                <a href="/tasklist/"><input type="button" value="返回" class="btn"></a>
        </p>
    </form>
    </div>
{% endblock %}

最终的效果如下所示:


如果用户没有输入足够的信息,将提示错误信息如下:


如果用户所有的信息都填正确,则提交成功,提示成功信息:


点击OK,返回任务列表,排在第1的就是刚刚创建的任务:



原文地址:https://www.cnblogs.com/riskyer/p/3325001.html