2012-08-12 74 views
13

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

我有一个名为vms的工作应用程序。使用models.py我有一个简单的模式,包含大小和类型。大小包括“小”,“中”&“大”。类型是'windows'&'linux'。使用管理网站,我可以添加额外的大小,例如“超大”。

我想要做的是创建一个窗体,它具有vm大小的下拉列表。如果通过管理站点添加了额外的大小,我希望该大小出现在下拉列表中。

我会在代码中提交我的尝试,但实际上我正在努力应对这些概念。任何人都可以帮助指导我如何完成上述?

感谢 奥利

+2

阅读教程https://docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs/和https://docs.djangoproject.com/en/dev/topics/forms/?from = olddocs。 – 2012-08-12 15:23:41

+0

我见过这两篇文章,我会再读一遍。我希望了解表单,视图和模板之间的关系,以及如何创建一个下拉列表..我想也许它只是带我有时间消化..如果其他人可以腾出时间解释这一点,我会非常高兴! – Oli 2012-08-12 16:27:30

回答

30

表单只是简化和加速(开发)从请求中获取POST数据的过程的工具。手动的方式是为所有的字段做一些HTML格式的request.POST.get('somefield')。但是Django的可以做的比这更好的...

在本质上,一个Form类包含若干领域,并执行以下任务:

  1. 显示HTML输入,
  2. 收集和验证数据时用户提交它
  3. 如果字段不验证,则返回值和错误消息为HTML
  4. 如果所有字段都是有效的,请提供form.cleaned_data字典作为访问这些值的便捷方式。

使用这些值,我可以手动创建一个MyModel的新实例并保存它。当然,我必须在MyModel模型中的每个字段的表单中定义一个字段。

这意味着,基本上,我可以做这样的事情:
(原谅我没有测试此代码,所以我不能保证它的正确率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) 

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

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

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

对于这个例子(和现实世界的例子很多),Django的可以做的比这更好的...

您可以注意到在上面例如两个恼人的问题:

  1. 我有分别在MyModelFormForMyModel的字段上定义字段。然而,这两个字段组(类型)之间有很多相似之处,所以这是一种重复的工作。当添加标签,验证程序等时,相似性会增加。
  2. 创建MyModel实例有点愚蠢,必须手动分配所有这些值。

这是一个的ModelForm用武之地。

这些行为基本上就像一个普通的形式(实际上,他们从常规模式扩展),但他们能救我的一些工作(我刚刚概述的两个问题当然是:))。

所以回到两个问题:

  1. 而不是定义表单字段为每个模型场,我只是在该Meta类中定义model = MyModel。这指示表单自动从模型字段生成表单字段。

  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) 

希望这清除了的Django的使用形成了一个位。

只需再注意一点 - 在ModelForm上定义表单域是完全可以的。这些将不会在form.save()中使用,但仍可以使用form.cleaned_data,就像使用常规表单一样。

+0

嗨 - 感谢您的帖子。我现在要给出一个解决方案,我会随着进展回到你身边 - 事实上我发现你的文章与我读过的一些文档相似,但你已经包含了一些明确的例子。这一定会帮助把它放在一起..希望很快会到达那里.. – Oli 2012-08-12 19:06:29

+1

嘿 - 我的表单现在工作..在第一个障碍 - 感谢您的帮助。连同这个问题中的例子,docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs和docs.djangoproject.com/en/dev/topics/forms/?from=olddocs和这个网站, peachybits.com/2011/09/django-1-3-form-api-modelform-example我能够解决这个问题。 – Oli 2012-08-13 14:42:23

2

你有没有试着用ModelForms前的工作?据我了解,你正在寻找创建一个基于你创建的模型的表单吗?

可以说你的模型叫做Temp。您可以创建与此模型(和你的问题)相关形式是这样的:

forms.py

from django.forms import ModelForm 

class TempForm(ModelForm): 
    class Meta: 
    model = Temp 

的的ModelForm会从模型的选择/选择自动映射到一个表单版本。

如果你打算在模板中使用这个以后,做这样的事情会自动创建一个选项的下拉菜单:

<form> 
    <label for="id_size">Size</label> 
    {{ form.size }} 
</form> 

希望这回答您的问题!

+1

感谢您的回答..我会尽力让这一切。我实际上遇到了这个网站,http://www.peachybits.com/2011/09/django-1-3-form-api-modelform-example/,即使它是django 1.3,我可以看到使用的概念。当我理解你的例子时,我会回到你身边。刚刚克服最初的障碍似乎很难,但一旦得到它,我相信它会轻松流动。 – Oli 2012-08-12 19:03:45

+0

嘿 - 我的表单现在可以工作了。在第一关 - 感谢您的帮助。连同这个问题中的例子,docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs和docs.djangoproject.com/en/dev/topics/forms/?from=olddocs和这个网站, peachybits.com/2011/09/django-1-3-form-api-modelform-example我能够解决这个问题。 – Oli 2012-08-13 14:42:05