Django 1.8.3 - 使用相关对象进行模型字段验证
Django 1.8.3 - model field validation with related object
对于以下模型集(Foo、Bar),您可以强加交叉验证规则,如以下代码片段 Bar.clean 中的规则,直到 django 1.7。
同一代码段在 django 1.8.3 中引发 RelatedObjectDoesNotExist
错误。
在 django 1.8.3 中实现相同结果的新改进方法是什么?
(我包含 admin.py 代码只是为了展示如何使用这些模型。)
models.py
from django.db import models
from django.core.exceptions import ValidationError
class Foo(models.Model):
name = models.CharField("Name", blank=True, max_length=300)
class Bar(models.Model):
name = models.CharField("Name", blank=True, max_length=300)
foo = models.ForeignKey('Foo', verbose_name='Foo')
def clean(self):
if self.name + self.foo.name != 'FooBar':
raise ValidationError('Concatenation should be FooBar.')
admin.py
from django.contrib import admin
import models
class BarInline(admin.TabularInline):
model = models.Bar
class FooAdmin(admin.ModelAdmin):
model = models.Foo
inlines = [BarInline,]
site = admin.site
site.register(models.Foo,FooAdmin)
我已经对您的代码添加了一个简单的输出修改
def clean(self):
print(self.__dict__)
if self.name + self.foo.name != 'FooBar':
raise ValidationError('Concatenation should be FooBar.')
简单的打印语句将在执行主代码之前打印出 Bar 对象。
现在我已经用 Django 1 测试了代码。8.x 我遇到了你提到的异常,结果如下:
{'_state': <django.db.models.base.ModelState object at 0x7ff55cd30710>, 'id': None, 'foo_id': None, 'name': 'Bar 1'}
现在又用Django 1测试了。7.x 运行正常,输出结果为:
{'_foo_cache': <Foo: Foo object>, 'name': 'Bar 1', 'id': None, 'foo_id': None, '_state': <django.db.models.base.ModelState object at 0x7f731151c9e8>}
正如您可能注意到 None
两种情况下的 foo_id
但神奇的是 _foo_cache
在 Django 1.8
中删除的东西
我可以建议您的替代方法是将您的验证移动到表单中
进行了以下更改:
admin.py
class BarInline(admin.TabularInline):
model = Bar
form = BarForm
forms.py
class BarForm(forms.models.ModelForm):
class Meta:
model = Bar
fields = ('name',)
def clean(self):
data = self.cleaned_data
if not data['name'] + data['foo'].name == "foobar":
raise ValidationError('Concatenation should be FooBar.')
对于以下模型集(Foo、Bar),您可以强加交叉验证规则,如以下代码片段 Bar.clean 中的规则,直到 django 1.7。
同一代码段在 django 1.8.3 中引发 RelatedObjectDoesNotExist
错误。
在 django 1.8.3 中实现相同结果的新改进方法是什么?
(我包含 admin.py 代码只是为了展示如何使用这些模型。)
models.py
from django.db import models
from django.core.exceptions import ValidationError
class Foo(models.Model):
name = models.CharField("Name", blank=True, max_length=300)
class Bar(models.Model):
name = models.CharField("Name", blank=True, max_length=300)
foo = models.ForeignKey('Foo', verbose_name='Foo')
def clean(self):
if self.name + self.foo.name != 'FooBar':
raise ValidationError('Concatenation should be FooBar.')
admin.py
from django.contrib import admin
import models
class BarInline(admin.TabularInline):
model = models.Bar
class FooAdmin(admin.ModelAdmin):
model = models.Foo
inlines = [BarInline,]
site = admin.site
site.register(models.Foo,FooAdmin)
我已经对您的代码添加了一个简单的输出修改
def clean(self):
print(self.__dict__)
if self.name + self.foo.name != 'FooBar':
raise ValidationError('Concatenation should be FooBar.')
简单的打印语句将在执行主代码之前打印出 Bar 对象。
现在我已经用 Django 1 测试了代码。8.x 我遇到了你提到的异常,结果如下:
{'_state': <django.db.models.base.ModelState object at 0x7ff55cd30710>, 'id': None, 'foo_id': None, 'name': 'Bar 1'}
现在又用Django 1测试了。7.x 运行正常,输出结果为:
{'_foo_cache': <Foo: Foo object>, 'name': 'Bar 1', 'id': None, 'foo_id': None, '_state': <django.db.models.base.ModelState object at 0x7f731151c9e8>}
正如您可能注意到 None
两种情况下的 foo_id
但神奇的是 _foo_cache
在 Django 1.8
我可以建议您的替代方法是将您的验证移动到表单中
进行了以下更改: admin.py
class BarInline(admin.TabularInline):
model = Bar
form = BarForm
forms.py
class BarForm(forms.models.ModelForm):
class Meta:
model = Bar
fields = ('name',)
def clean(self):
data = self.cleaned_data
if not data['name'] + data['foo'].name == "foobar":
raise ValidationError('Concatenation should be FooBar.')