Django - 使用full_clean()验证管理错误

时间:2013-11-18 15:15:18

标签: python django django-forms django-views

我使用modelformset_factory,并使用full_clean()来验证具有unique_together = True的表单。我想知道在unique_together不验证的情况下处理错误的最佳方法是什么,以便在模板中返回错误消息。

请查看我的观点,并告诉我,如果我改变了我的方式,或者是否有更好的方法。

模型:

class Attribute(models.Model):
    shapefile = models.ForeignKey(Shapefile)
    name = models.CharField(max_length=255, db_index=True)
    type = models.IntegerField()
    width = models.IntegerField()
    precision = models.IntegerField()

    def __unicode__(self):
        return self.name

    def delete(self):
        shapefile = self.shapefile
        feature_selected = Feature.objectshstore.filter(shapefile=shapefile)
        feature_selected.hremove('attribute_value', self.name)
        super(Attribute, self).delete()

    class Meta:
        unique_together = (('name', 'shapefile'),)

形式:

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['type'].required = False
            self.fields['width'].widget.attrs['readonly'] = True
            self.fields['precision'].widget.attrs['readonly'] = True


    def clean_type(self):
        if self.instance and self.instance.pk:
            return self.instance.type
        else:
            return self.cleaned_data['type']

    type = forms.ChoiceField(choices=FIELD_TYPE)

    class Meta:
        model = Attribute
        exclude = 'shapefile'

视图:

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)
        if formset.is_valid():
            instances = formset.save(commit=False)
            for instance in instances:
                instance.shapefile = layer_selected
                try:
                    instance.full_clean()
                except ValidationError as e:
                    non_field_errors = e.message_dict[NON_FIELD_ERRORS]
                    print non_field_errors
                    formset = attributesFormset(queryset=attributes_selected)
                    return render_to_response("basqui/manage_layer_editFields.html", {'shapefile': layer_selected, 'formset':formset}, context_instance=RequestContext(request))
                instance.save()

    formset = attributesFormset(queryset=attributes_selected)
    return render_to_response("basqui/manage_layer_editFields.html", {'shapefile': layer_selected, 'formset':formset}, context_instance=RequestContext(request))

1 个答案:

答案 0 :(得分:1)

您的方法的缺点是您已将验证从表单移至视图。

我最近遇到了同样的问题,即验证一个唯一的约束,其中一个字段从模型表单中排除。我的解决方案是覆盖模型表单的clean方法,并查询数据库以检查唯一的约束。这复制了full_clean调用的代码,但我喜欢它,因为它是显式的。

我简单地想过覆盖_get_validation_exclusions,这本来会更干,但我决定不依赖私人api。