Bel*_*dar 1 django django-forms
我使用 modelform_factory 生成带有额外表单的模型表单。对于带有实例的表单,类型字段被禁用,对于额外的表单,该字段被启用。
在 save() 时,表单不会验证,因为禁用字段的 POST 中没有数据。即使自定义清洁方法也不起作用(请参阅此答案)。我想跳过对禁用字段的验证,或者有办法保留该字段的实例数据。
模型.py
class Attribute(models.Model):
shapefile = models.ForeignKey(Shapefile)
name = models.CharField(max_length=255)
type = models.IntegerField()
width = models.IntegerField()
precision = models.IntegerField()
def __unicode__(self):
return self.name
Run Code Online (Sandbox Code Playgroud)
表格.py
FIELD_TYPE = [('', '--Choose a type--'),
(0, 'Integer'),
(1, 'Integer list'),
(2, 'Double Precision Float'),
(3, 'List of doubles'),
(4, 'String of ASCII chars'),
(5, 'Array of strings'),
(8, 'Raw Binary data'),
(9, 'Date'),
(10, 'Time'),
(11, 'Date and Time')]
class AttributeForm(ModelForm):
def __init__(self, *args, **kwargs):
super(AttributeForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['type'].widget.attrs['disabled'] = True
self.fields['width'].widget.attrs['readonly'] = True
self.fields['precision'].widget.attrs['readonly'] = True
type = forms.ChoiceField(choices=FIELD_TYPE)
class Meta:
model = Attribute
exclude = ['shapefile']
Run Code Online (Sandbox Code Playgroud)
视图.py
def editFields(request, shapefile_id):
layer_selected = Shapefile.objects.get(pk=shapefile_id)
attributes_selected= Attribute.objects.filter(shapefile__pk=shapefile_id)
attributesFormset = modelformset_factory(Attribute, form=AttributeForm, extra=1, can_delete=True)
if request.POST:
formset = attributesFormset(request.POST, queryset=attributes_selected)
formset.save()
else:
formset = attributesFormset(queryset=attributes_selected)
return render_to_response("ezmapping/editFields.html", {'shapefile': layer_selected, 'formset':formset}, context_instance=RequestContext(request))
Run Code Online (Sandbox Code Playgroud)
有很多方法,但我认为这个相当优雅(假设它确实有效;第一次检查时它看起来很正确,但我还没有测试过)。
在表单上,有条件地将字段设置为不需要,然后声明自定义 clean 方法:
def __init__(self):
# as above, until here
self.fields['type'].widget.attrs['disabled'] = True
self.fields['type'].required = False
# then continue as above
def clean_type(self):
if self.instance and self.instance.pk:
return self.instance.type
else:
return self.cleaned_data['type']
Run Code Online (Sandbox Code Playgroud)
将其设置为不需要意味着该字段在验证该字段期间不会立即短路,并且该字段的自定义 clean 方法返回实例的未修改值,以便在None从表单构造修改后的实例时不会覆盖该值。对于给定空值或根本没有值的必填字段,不会调用自定义清理方法。
| 归档时间: |
|
| 查看次数: |
3242 次 |
| 最近记录: |