Django 1.8.3 - 具有相关对象的模型字段验证
Posted
技术标签:
【中文标题】Django 1.8.3 - 具有相关对象的模型字段验证【英文标题】:Django 1.8.3 - model field validation with related object 【发布时间】:2015-10-01 00:45:12 【问题描述】:对于以下一组模型(Foo、Bar),您可以施加交叉验证规则,如以下代码 sn-p 至 django 1.7 的 Bar.clean 中的规则。
同样的 sn-p 在 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)
【问题讨论】:
【参考方案1】:我在您的代码中添加了一个简单的输出修改
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
,但神奇的是在Django 1.8 中删除的_foo_cache
东西
我可以建议您的替代方法是将您的验证移到表单中
进行了以下更改: 管理员.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.')
【讨论】:
这个自省非常有用,谢谢。您是否知道为什么 Django 开发人员会从模型 clean() 方法中删除查询相关对象的功能,这似乎很方便?以上是关于Django 1.8.3 - 具有相关对象的模型字段验证的主要内容,如果未能解决你的问题,请参考以下文章