我在StackOverflow中阅读了关于forms.Form
vs forms.ModelForm
的一些帖子。
似乎当表单的数据库中已有表时,最好使用ModelForm
,这样就不必再次声明所有属性,因为它们已存在于相应的类中model.py
所以我的问题是
如何排除原始类的一系列属性,以下是排除表达式okie?
class CreatePositionForm(ModelForm):
class Meta:
model = job_position
exclude = ('create_date','post_date','is_valid',)
使用ModelForm时,是否意味着原始属性不应该更改,并且在Meta类之前不会再有代码?(就像上面的代码一样)
任何人都可以告诉我使用表单而不仅仅是HTML的好处 表单标签,除了它有助于报告错误
form.field_name.errors
我是Django的新学员,如果这些问题看起来很愚蠢,请耐心等待,非常感谢你的澄清!
答案 0 :(得分:2)
似乎“验证”对3来说是一个很大的答案 - 它通常是Web框架的一个主要特征。至于不使用HTML标签,还有DRY principle:如果您已经定义了表单的字段(用于验证目的),为什么还要在模板中复制它?有一个关于表单外观的单一事实来源(在Django中,Form
个对象,或ModelForm
和Model
s),并派生出来你可以从那个单一的来源(HTML)。
答案 1 :(得分: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上的字段属性,这是一个很大的优点。 从这些开始,它可以减少编写html的开销,同时开发以检查功能。
答案 2 :(得分:1)
exclude
should be a list(虽然您也可以使用元组,但只需引用文档,请参阅注释)。您应该将其更改为 -
exclude = ['create_date','post_date','is_valid']
没有那样的。你可以改变你想要的任何东西。您可以添加自定义窗口小部件,更改窗体域属性,甚至可以向其添加更多窗体域。 ModelForm
只是使您的模型和表单更加耦合,以便正确地进行验证。如果您使用Form
代替模型所具有的相同字段,则必须重新定义字段类型。
使用Form
可以减轻您管理字段属性的难度。如果您在模型中更改某些内容,更改将自动反映到表单的HTML。您不必每次都手动更改HTML。它还可以帮助您进行自动验证。
答案 3 :(得分:1)
Form和ModelForm都扩展了同一个类:
class BaseModelForm(BaseForm)
class Form(BaseForm)
所以:
可以这样排除,但问题出在保存时:如果需要或者没有默认值,则必须处理代码中的排除字段
您可以向ModelForm对象添加额外的属性:
类CreatePositionForm(ModelForm):
new_field = forms.CharField(max_length = 100)
class Meta:
model = job_position
exclude =('create_date','post_date','is_valid',)
但是你必须将它们包含在字段列表中(如果你想渲染它们):
.... 类Meta: .... fields = [...,'new_field',...]
保存时,您需要照顾该字段。
表单具有基于您使用的FormField和Widget类型的默认验证。 ModelForms还具有基于模型字段的验证,每个字段/每个表单的错误报告,直接保存到数据库。除此之外,我发现在使用formset(每页多个表单)时更容易使用modelforms。
答案 4 :(得分:1)
正如django docs所述:
如果您正在构建一个数据库驱动的应用程序,那么您可能会拥有与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为您执行验证并显示表单错误。
现在回答你的问题,
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')
我真的不明白你的意思original attributes are not supposed to be changed
???
使用ModelForm的好处
答案 5 :(得分:0)
你可以使用ModelForm并更改原始属性,但在大多数情况下Django做得很好!
Django表单非常有用,您可以执行高级验证,添加一些业务逻辑。好吧,django Forms呈现HTML,但即使你的Django项目不提供HTML,你可能仍在使用Django表单。
您的排除代码似乎没问题,但请注意使用Meta.excludes
被视为安全风险。使用Meta.fields