2

我在 StackOverflow 中阅读了一些关于forms.Formvs的文章forms.ModelForm

似乎当表单的数据库中已经有一个表时,最好使用ModelForm这样您就不必再次声明所有属性,因为它们已经存在于model.py中的相应类中

所以我的问题是

  1. 如何排除原类的一系列属性,下面的排除表达式okie吗?

    class CreatePositionForm(ModelForm):  
        class Meta:  
            model = job_position 
            exclude = ('create_date','post_date','is_valid',)
    
  2. 使用ModelForm的时候,是不是说原来的属性不应该改变,在Meta类之前就没有代码了?(和上面的代码一样)

  3. 任何人都可以告诉我使用表单而不是简单的 HTML 表单标签有什么好处,除了它有助于报告错误

    form.field_name.errors
    

    我是 Django 的新手,如果这些问题看起来很愚蠢,请多多包涵,非常感谢您的澄清!

4

6 回答 6

2

似乎“验证”是对 3 的一个重要答案——它通常是 Web 框架的一个主要特性。至于不使用 HTML 标签,有一个DRY 原则:如果您已经定义了表单的字段是什么(出于验证目的),为什么还要在模板中复制它?拥有关于表单外观的单一事实来源Form(在 Django 中,对象或ModelForms 与Models 一起),并从该单一来源派生出你能做什么(HTML)。

于 2013-05-28T10:32:30.153 回答
2

1-是的,可以使用,

exclude = ['create_date','post_date','is_valid']

更多关于模型形式在这里- https://docs.djangoproject.com/en/dev/topics/forms/modelforms/

2-您不能更改模型表单的属性是错误的,您可以通过在类中定义为相同的属性来覆盖它,您可以像普通表单一样执行任何操作来覆盖初始、选择等 exa -

from django.forms import ModelForm, DateField
class CreatePositionForm(ModelForm):
    created_date = DateField(label="when created")
    def __init__( self, *args, **kwargs ):
        super( CreatePositionForm, self ).__init__( *args, **kwargs )
        self.fields['your_choice_field'].choices = choice_list 
    class Meta:  
        model = job_position 
        exclude = ['create_date','post_date','is_valid']

3- 最有价值的好处是它自己启用表单验证,如果您编写自己的 html,您将不得不编写长行代码。对于 exa - 你给了一个 char 字段,它会抛出一个错误,并将错误类添加到 html 上的 field 属性,这是一个很大的优势。从这些开始,它减少了在开发检查功能时编写 html 的开销。

于 2013-05-28T10:41:25.213 回答
1
  1. exclude应该是一个列表(虽然你也可以使用元组,只是引用文档,见评论)。你应该把它改成——

    exclude = ['create_date','post_date','is_valid']
    
  2. 没有那样的事。你可以改变任何你想要的东西。您可以添加自定义小部件、更改表单字段属性,甚至添加更多表单字段。ModelForm只是使您的模型和表单更加耦合,以便正确完成验证。如果您改用Form模型具有的相同字段,则必须重新重新定义字段类型。

  3. 使用 aForm可以减少管理字段属性的麻烦。如果您更改模型中的某些内容,更改将自动反映到表单的 HTML。您不必每次都手动更改 HTML。它还可以帮助您进行自动验证。

于 2013-05-28T10:28:40.400 回答
1

Form 和 ModelForm 都扩展同一个类:

class BaseModelForm(BaseForm)
class Form(BaseForm)

所以:

  1. 可以这样排除,但问题在于保存时:如果需要或没有默认值,则必须处理代码中的排除字段

  2. 您可以向 ModelForm 对象添加额外的属性:

    class CreatePositionForm(ModelForm):
    new_field = forms.CharField(max_length=100) class Meta:
    model = job_position exclude = ('create_date','post_date','is_valid',) 但是你必须将它们包含在字段列表中(如果你想渲染它们):

    .... 类 Meta: .... 字段 = [...,'new_field',...]

    保存时,您需要注意该字段。

  3. 表单具有基于您使用的 FormField 和 Widget 类型的默认验证。ModelForms 还具有基于模型字段的验证,每个字段/每个表单的错误报告,保存直接到数据库。最重要的是,我发现在使用表单集(每页多个表单)时使用模型表单更容易。

于 2013-05-28T10:45:53.610 回答
1

正如 django 文档所述:

如果您正在构建一个数据库驱动的应用程序,那么您很可能拥有与 Django 模型紧密映射的表单。例如,您可能有一个 BlogComment 模型,并且您想创建一个允许人们提交评论的表单。在这种情况下,在表单中定义字段类型是多余的,因为您已经在模型中定义了字段。

出于这个原因,Django 提供了一个帮助类,让您可以从 Django 模型创建一个 Form 类。

当您需要与任何已定义模型密切相关的表单时,ModelForm 非常有用。ModelForm 相对于form.Form类的优点是您不需要编写额外的代码。例如:假设您有一个定义如下的模型:

class Profile(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()
    phone = models.IntegerField()
    profile_summary = models.TextField()
    # .. some more fields ..

现在让我们使用 3 种不同的方法创建一个表单,看看哪一种最容易实现。

简单的 HTML 表单

对于纯 HTML 表单,您需要在模板中实现表单元素,然后自己验证数据,如下所示。

<form id="profile-form">
    <div>
        <label>First Name</label>
        <input name="first_name" type="text" />
    </div>
    <div>
        <label>Last Name</label>
        <input name="last_name" type="text" />
    </div>
    <div>
        <label>Email</label>
        <input name="email" type="text" />
    </div>
    <div>
        <label>Phone Number</label>
        <input name="phone" type="text" />
    </div>
    <div>
        <label>Profile Summary</label>
        <textarea name="profile_summary"></textarea>
    </div>
</form>

然后在视图中:

def update_profile(request):
    if request.method == 'POST'
        first_name = request.POST.get('first_name')
        # Do this for all the fields and validate them 
        # manually

使用 forms.Form 类

使用django.forms.Form该类,您可以定义如下形式

from django import forms

class ProfileForm(forms.Form):
    first_name = forms.CharField()
    last_name = forms.CharField()
    email = forms.EmailField()
    phone = forms.IntegerField()
    summary = forms.TextField()
    # Notice the code duplication here
    # we already have this defined in our models.

使用 ModelForm 类

from django import forms

class ProfileForm(forms.ModelForm)
    class Meta:
        model = models.Profile

因此,使用ModelForm类您可以在 4-5 行代码内简单地创建表单,并让 django 为您进行验证并显示表单错误。

现在回答你的问题,

  1. 有两种方法可以从表单类中排除特定字段。您可以使用exclude或定义fields.

排除

from django import forms

class ProfileForm(forms.ModelForm)
    class Meta:
        model = models.Profile
        exclude = ('phone',)

字段

from django import forms

class ProfileForm(forms.ModelForm)
    class Meta:
        model = models.Profile
        fields = ('first_name', 'last_name', 'email', 'profile_summary')
  1. 我真的不明白你的意思是什么original attributes are not supposed to be changed???

  2. 使用 ModelForm 的好处

    • 更少的代码/没有代码重复
    • 表单验证
    • 表单错误
    • 快的
    • 漂亮的代码
于 2013-05-28T10:47:33.380 回答
0

您可以使用 ModelForm 并更改原始属性,但在大多数情况下 Django 做得很好!

Django 表单非常有用,可以执行高级验证,添加一些业务逻辑。好吧,django Forms 渲染 HTML,但即使您的 Django 项目不提供 HTML,您可能仍在使用 Django 表单。

您的排除代码似乎没问题,但请注意,使用Meta.excludes被视为安全风险。采用Meta.fields

于 2013-05-28T10:27:40.053 回答