我有一个带有自定义模型字段的模型表单。
class UserModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.get_full_name()
class TaskForm(forms.ModelForm):
originator = UserModelChoiceField(queryset=User.objects.all().order_by('first_name'),widget=forms.Select(attrs={'class':'form-control'}))
class Meta:
model = Task
fields = ['originator']我的阅读表明,以这种方式处理我的字段将覆盖来自模型的任何信息(例如,是否需要它),因为它正在从我的定义中实例化它,而不是增强模型的字段。
看来,为了尽量减少对这样的字段的修改,我应该与init交互(见下文)。
def __init__(self,*args, **kwargs):
super(TaskForm, self).__init__(*args, **kwargs)
self.fields['originator'].queryset=User.objects.all().order_by('first_name')
self.fields['originator'].widget = forms.Select(attrs={'class':'form-control'})假设上面的内容是正确的,我理解如何做queryset和小部件。我的问题是我该如何使用那个定制的选项场。此外,我甚至不确定这是否是这样做的方式,因为它似乎有点麻烦。
发布于 2016-07-09 16:11:43
呃..。我记得我有这个问题,没有找到一个内置的或惯用的解决方案。我没有想出比这个装饰师更好的解决方案(是的,这是生产代码):
def model_generated(model):
"""Generate form fields from model fields
Purpose:
This decorator lets you have form field attributes like
`max_length` copied over from a model field while being DRY.
Usage:
Decorate a form class with this decorator and set MODEL_GENERATED_FIELDS
to a list of attribute names you would like to be generated.
Limitations:
- Currently, this decorator only supports CharFields.
"""
def decorator(cls):
for field_name in cls.MODEL_GENERATED_FIELDS:
model_field = model._meta.get_field(field_name)
model_field_type = type(model_field)
if model_field_type == django_models.CharField:
form_field_type = forms.CharField
attributes = { # (form_attribute, model_attribute, processor)
('label', 'verbose_name', None),
('max_length', None, None),
('min_length', None, None),
('required', 'blank', lambda value: not value),
}
else:
# (Maybe one day this decorator will support more types of fields.)
raise ValueError("Unknown type of model field: {}".format(model_field_type))
kwargs = {}
for form_attribute, model_attribute, processor in attributes:
if model_attribute is None:
model_attribute = form_attribute
if processor is None:
processor = lambda value: value
if hasattr(model_field, model_attribute):
kwargs[form_attribute] = processor(getattr(model_field, model_attribute))
form_field = form_field_type(**kwargs)
setattr(cls, field_name, form_field)
# Register field since we're monkey-patching
# (Django's meta-class hackery to detect fields only runs the first time the class is declared.)
cls.base_fields[field_name] = form_field
return cls
return decorator所以,举个例子,我会:
class Team(models.Model):
name = models.CharField(max_length=30, unique=True,
verbose_name="Team Name")
passphrase = models.CharField(max_length=30,
verbose_name="Passphrase")
...以及:
@model_generated(models.Team)
class TeamJoiningForm(forms.Form):
MODEL_GENERATED_FIELDS = ('name', 'passphrase')
...您可以根据自己的特定需求调整和扩展model_generated装饰器。抱歉的。
https://stackoverflow.com/questions/38235623
复制相似问题