创建django表单

Oli*_*Oli 15 python django django-forms

我正在努力让我的头脑旋转django形式..我一直在阅读各种文档,但只是不能完全掌握这些概念.我必须掌握模型,视图和模板.我要做的是创建一个包含下拉列表和复选框的各种字段的表单,这些复选框由数据库中的值填充.

我有一个名为vms的应用程序.使用models.py我有一个构建一个包含大小和类型的简单模式.大小由'小','中'和'大'组成.类型是'windows'和'linux'.使用管理站点,我可以添加额外的大小,例如"超大".

我想要做的是创建一个具有vm大小下拉列表的表单.如果通过管理站点添加了额外的大小,我希望该大小显示在下拉列表中.

我会提交我对代码的尝试,但实际上我正在努力解决这些问题.任何人都可以帮助指导我如何完成上述任务?

谢谢奥利

frn*_*nhr 33

表单只是简化和加速(开发)从请求中获取POST数据的过程的工具.request.POST.get('somefield')对于某些HTML表单中的所有字段,将采用手动方式.但是Django可以做得更好......

从本质上讲,Form类包含许多Fields并执行以下任务:

  1. 显示HTML输入,
  2. 用户提交数据时收集和验证数据,
  3. 如果字段未验证,则将值与错误消息一起返回到HTML,
  4. 如果所有字段都验证,则提供form.cleaned_data字典作为在视图中访问这些值的便捷方式.

有了这些值,我就可以手动创建一个新的实例MyModel并保存它.当然,我必须在MyModel模型中为每个Field定义一个Field.

这意味着,基本上,我可以这样做:(
原谅我没有测试这段代码,所以我不能保证它是100%正确的)

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class FormForMyModel(forms.Form):
        form_field1 = forms.CharField(max_length=40, required=True)
        form_field2 = forms.CharField(max_length=60, required=False)

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = FormForMyModel(request.POST)
            if form.is_valid():
                my_model = MyModel()
                my_model.field1 = form.cleaned_data.get('form_field1', 'default1')
                my_model.field2 = form.cleaned_data.get('form_field2', 'default2')
                my_model.save()
        else:        
            form = FormForMyModel()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)
Run Code Online (Sandbox Code Playgroud)

(这可以用少量代码编写,但它应尽可能清晰)

请注意,模型字段和表单字段之间没有关系!我们必须在创建MyModel实例时手动为其分配值.

上面的示例概述了通用表单工作流程.在复杂情况下经常需要它,但不是像这个例子那样简单.

对于这个例子(以及很多真实世界的例子),Django可以做得更好......

您可以在上面的示例中发现两个恼人的问题:

  1. 我必须分别定义Fields on MyModel和Fields FormForMyModel.但是,这两个字段组(类型)之间存在很多相似之处,因此这是一种重复的工作.添加标签,验证器等时,相似性会增加.
  2. 创建MyModel实例有点傻,必须手动分配所有这些值.

这就是ModelForm的用武之地.

这些行为基本上就像一个常规形式(实际上,它们从常规形式扩展而来),但它们可以节省我的一些工作(我刚才概述的两个问题,当然:)).

回到这两个问题:

  1. 我没有为每个模型字段定义一个表单Field,而只是model = MyModelMeta类中定义.这指示表单从模型字段自动生成表单字段.

  2. 模型表格有save可用的方法.这可用于在视图中的一行中创建模型实例,而不是手动分配逐个字段.

所以,让我们用上面的例子做一个ModelForm:

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class MyModelForm(forms.ModelForm):  # extending ModelForm, not Form as before
        class Meta:
            model = MyModel

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = MyModelForm(request.POST)
            if form.is_valid():
                # save the model to database, directly from the form:
                my_model = form.save()  # reference to my_model is often not needed at all, a simple form.save() is ok
                # alternatively:
                # my_model = form.save(commit=False)  # create model, but don't save to database
                # my.model.something = whatever  # if I need to do something before saving it
                # my.model.save()
        else:        
            form = MyModelForm()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)
Run Code Online (Sandbox Code Playgroud)

希望这能清除Django表单的用法.

还有一个注意事项 - 在a上定义表单字段是完全可以的ModelForm.这些不会被使用,form.save()但仍然可以form.cleaned_data像普通表格一样访问.