Django表单字段验证 - 如何判断操作是插入还是更新?

时间:2012-10-03 11:44:56

标签: django django-models django-forms django-validation

我正在尝试在Django中执行此操作: 在Admin中保存对象时,我想根据我的第一个对象中的一个字段保存另一个不同类型的对象。 为了做到这一点,我必须检查第二个对象是否已经存在,并且只返回第一个对象中特定字段的验证错误。 我的问题是,只有当操作是插入时,我才希望验证错误出现在字段中。

如何根据知道操作是更新还是插入来显示特定管理表单字段的验证错误?

P.S。我知道,对于模型验证,这是不可能的,因为验证器只接受value参数,但我认为应该可以进行表单验证。

4 个答案:

答案 0 :(得分:6)

这可以通过在Django Admin Form中编写clean_ [name_of_field]方法来完成。可以通过测试self.instance.pk。

来检查插入或更新操作
class EntityAdminForm(forms.ModelForm):
    def clean_field(self):
        field = self.cleaned_data['field']
        insert = self.instance.pk == None
        if insert:
            raise forms.ValidationError('Some error message!')
        else:
            pass
        return field

class EntityAdmin(admin.ModelAdmin):
    form = EntityAdminForm

在向Django管理员注册实体模型时,您必须使用EntityAdmin类:

admin.site.register(Entity, EntityAdmin)

答案 1 :(得分:0)

您可以撰写custom validation at the model level

#inside your class model ...
def clean(self):
    is_insert = self.pk is None
    from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
    #do your business rules
    if is_insert:
        ...
        if __some_condition__ :
            raise ValidationError('Dups.')

答案 2 :(得分:0)

为您的模型创建模型表单。在clean方法中,您可以为特定字段设置错误。

有关详细信息,请参阅cleaning and validating fields that depend on each other的文档。

答案 3 :(得分:0)

那可能(可能)不是一个确切的答案,但我想这可能会有所帮助。

Django Admin允许您使用ModelAdmin.save_model方法(doc is here)覆盖save方法

Django api也有一个get_or_create方法(Doc is here)。它返回两个值,第一个是对象,第二个是布尔值,表示是否创建了对象(更新现有记录)。

我说你有FirstObjectSecondObject

在相关的admin.py文件中:

class FirstObjectAdmin(admin.ModelAdmin):
...
...
    def save_model(self, request, obj, form, change):
        s_obj, s_created = SecondObject.objects.get_or_create(..., defaults={...})
        if not s_created:
            #  second object already exists... We will raise validation error for our first object
            ...

对于其他人,我对如何处理它并不清楚。由于您手边有表单对象,因此可以调用form.fields{'somefield'].validate(value)write a custom validation for admin。您可能会覆盖clean方法并尝试从raise ValidationError方法触发ModelAdmin.save_model。你可以拨打validate并从那里传递一个值......

您可以挖掘django源以了解django如何处理此问题,并尝试定义一些自定义验证步骤。