我使用 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
表格.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']
视图.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))