For the following set of models (Foo, Bar), you could impose a cross-validation rule like the one in the Bar.clean of the following code snippet up to django 1.7.
对于以下模型集(Foo,Bar),您可以将以下代码段的Bar.clean中的交叉验证规则强加到django 1.7。
The same snippet throws a RelatedObjectDoesNotExist
error in django 1.8.3.
相同的代码片段在django 1.8.3中引发了一个RelatedObjectDoesNotExist错误。
What is the new and improved way of achieving the same result in django 1.8.3?
在django 1.8.3中实现相同结果的新方法和改进方法是什么?
(I've included the admin.py code just to show how these models are being used.)
(我已经包含了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 个解决方案
#1
1
I've added a simple output modification to your code
我在代码中添加了一个简单的输出修改
def clean(self):
print(self.__dict__)
if self.name + self.foo.name != 'FooBar':
raise ValidationError('Concatenation should be FooBar.')
The simple print statements will print out Bar object before executing of main code.
简单的print语句将在执行主代码之前打印出Bar对象。
Now I've tested the code with Django 1.8.x and I've got the exception as you mentioned this is the result:
现在我用Django 1.8.x测试了代码,我得到了例外,因为你提到这是结果:
{'_state': <django.db.models.base.ModelState object at 0x7ff55cd30710>, 'id': None, 'foo_id': None, 'name': 'Bar 1'}
Now I've tested it again with Django 1.7.x and it works ok, the output result is:
现在我用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>}
As you may noticed the foo_id
in both cases in None
but what does the magic is the _foo_cache
thing that was removed in Django 1.8
您可能已经注意到两种情况下的foo_id都是None,但魔术是Django 1.8中删除的_foo_cache。
The substitute that I can suggest you is to move your validation into Forms
我建议你的替代方法是将你的验证转移到表格中
Made these changes : admin.py
做了这些更改: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.')
#1
1
I've added a simple output modification to your code
我在代码中添加了一个简单的输出修改
def clean(self):
print(self.__dict__)
if self.name + self.foo.name != 'FooBar':
raise ValidationError('Concatenation should be FooBar.')
The simple print statements will print out Bar object before executing of main code.
简单的print语句将在执行主代码之前打印出Bar对象。
Now I've tested the code with Django 1.8.x and I've got the exception as you mentioned this is the result:
现在我用Django 1.8.x测试了代码,我得到了例外,因为你提到这是结果:
{'_state': <django.db.models.base.ModelState object at 0x7ff55cd30710>, 'id': None, 'foo_id': None, 'name': 'Bar 1'}
Now I've tested it again with Django 1.7.x and it works ok, the output result is:
现在我用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>}
As you may noticed the foo_id
in both cases in None
but what does the magic is the _foo_cache
thing that was removed in Django 1.8
您可能已经注意到两种情况下的foo_id都是None,但魔术是Django 1.8中删除的_foo_cache。
The substitute that I can suggest you is to move your validation into Forms
我建议你的替代方法是将你的验证转移到表格中
Made these changes : admin.py
做了这些更改: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.')