Django forms.Form 反映 属性 字段约束
Django forms.Form reflecting property field constraints
我正在实施 Django 表单 应该包含来自 modelA
的字段 'fieldA':
class ModelA(models.Model):
fieldA = models.CharField(max_length=8)
...
我的问题是:有没有办法让 Django 表单自动处理字段 A 的验证(检查 max_length)?我知道我可以使用 form.ModelForm
class 来指代 ModelA,但随后该表单将反映 ModelA 的所有字段。我想使用简单的 forms.Form
.
我正在寻找类似这样的解决方案:
class formX(forms.Form):
fieldA = forms.CharField(**modelA.fieldA.constraints)
fieldB = ... some other fields not related to ModelA ...
.... even more fields
也许这个问题是XY问题,但让我试试...
直接问题:从现有模型中获取字段约束
from django import forms
from django.db import models
class Foo(models.Model):
x = models.CharField(max_length=30)
y = models.IntegerField(null=True)
class FooForm(forms.Form):
foo_x = forms.CharField(max_length=Foo._meta.get_field('x').max_length)
您可以通过两种方式直接访问该字段:
ModelClass.field_name.field
(有点乱七八糟,ModelClass.field_name
是 django.db.models.query_utils.DeferredAttribute
)
ModelClass._meta.get_field('field_name')
(更好的方法,在文档的某处描述)
但是,这样您必须 a) 如果添加了字段约束则更新表单或 b) 提前指定所有属性(max_length
、min_length
、verbose_name
、blank
, 等), 使 FooForm.foo_x
的声明过于冗长。
备选方案
字段子集
首先,如果您需要 Foo
个字段的子集,请使用 ModelForm
并指定它们:
class FooForm(forms.ModelForm):
class Meta:
fields = ('x',)
现在您有一个只有 x
字段的表单。
添加一些字段
如果您想向此表单添加字段(与其他模型无关),请这样做:
class FooForm(forms.ModelForm):
another_field = forms.IntegerField()
class Meta:
fields = ('x',)
def clean_another_field(self):
data = self.cleaned_data['another_field']
if data != 42:
raise ValidationError('Not an answer!') # i18n should be here
return data
您还可以覆盖 clean
和 save
方法以获得其他目标,documentation 解释得很好。
混合来自不同模型的字段
如果您需要两个不同模型的字段以一种形式出现,您不需要。在这种情况下,您需要两个单独的表单,加上一些 inter-validation 此表单之外的逻辑(例如,作为视图方法,或者作为另一个 class 即 not 一个表格)。也许你需要的是inline formset,它不代表两种混合形式,但至少有一些inter-model的沟通。
我找到了一种方法来实现对反映模型字段约束的表单字段的验证。
class Foo(models.Model):
x = models.CharField(max_length=30)
y = models.IntegerField(null=True)
class FooForm(forms.Form):
foo_x = forms.CharField(validators=Foo._meta.get_field('x').validators)
像这样,表单将尊重属性 x
的 max_length
验证器或定义的任何其他验证器。
我正在实施 Django 表单 应该包含来自 modelA
的字段 'fieldA':
class ModelA(models.Model):
fieldA = models.CharField(max_length=8)
...
我的问题是:有没有办法让 Django 表单自动处理字段 A 的验证(检查 max_length)?我知道我可以使用 form.ModelForm
class 来指代 ModelA,但随后该表单将反映 ModelA 的所有字段。我想使用简单的 forms.Form
.
我正在寻找类似这样的解决方案:
class formX(forms.Form):
fieldA = forms.CharField(**modelA.fieldA.constraints)
fieldB = ... some other fields not related to ModelA ...
.... even more fields
也许这个问题是XY问题,但让我试试...
直接问题:从现有模型中获取字段约束
from django import forms
from django.db import models
class Foo(models.Model):
x = models.CharField(max_length=30)
y = models.IntegerField(null=True)
class FooForm(forms.Form):
foo_x = forms.CharField(max_length=Foo._meta.get_field('x').max_length)
您可以通过两种方式直接访问该字段:
ModelClass.field_name.field
(有点乱七八糟,ModelClass.field_name
是django.db.models.query_utils.DeferredAttribute
)ModelClass._meta.get_field('field_name')
(更好的方法,在文档的某处描述)
但是,这样您必须 a) 如果添加了字段约束则更新表单或 b) 提前指定所有属性(max_length
、min_length
、verbose_name
、blank
, 等), 使 FooForm.foo_x
的声明过于冗长。
备选方案
字段子集
首先,如果您需要 Foo
个字段的子集,请使用 ModelForm
并指定它们:
class FooForm(forms.ModelForm):
class Meta:
fields = ('x',)
现在您有一个只有 x
字段的表单。
添加一些字段
如果您想向此表单添加字段(与其他模型无关),请这样做:
class FooForm(forms.ModelForm):
another_field = forms.IntegerField()
class Meta:
fields = ('x',)
def clean_another_field(self):
data = self.cleaned_data['another_field']
if data != 42:
raise ValidationError('Not an answer!') # i18n should be here
return data
您还可以覆盖 clean
和 save
方法以获得其他目标,documentation 解释得很好。
混合来自不同模型的字段
如果您需要两个不同模型的字段以一种形式出现,您不需要。在这种情况下,您需要两个单独的表单,加上一些 inter-validation 此表单之外的逻辑(例如,作为视图方法,或者作为另一个 class 即 not 一个表格)。也许你需要的是inline formset,它不代表两种混合形式,但至少有一些inter-model的沟通。
我找到了一种方法来实现对反映模型字段约束的表单字段的验证。
class Foo(models.Model):
x = models.CharField(max_length=30)
y = models.IntegerField(null=True)
class FooForm(forms.Form):
foo_x = forms.CharField(validators=Foo._meta.get_field('x').validators)
像这样,表单将尊重属性 x
的 max_length
验证器或定义的任何其他验证器。