本章通过实现一个用户提交任务请求的页面,讲述表单、视图、模型、模板间的交互。
首先,我们需要定义一个表单(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的就是刚刚创建的任务: