2015-07-12 78 views
6

對於下面的一組模型(Foo,Bar),您可以施加一個交叉驗證規則,如以下代碼段的Bar.clean中的交叉驗證規則,直到django 1.7。Django 1.8.3 - 使用相關對象進行模型字段驗證

相同的片段在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但到底是什麼神奇的是_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.') 
+1

自省是非常有用的,謝謝。你知道爲什麼Django開發人員會從模型clean()方法中刪除查詢相關對象的能力,這看起來相當方便嗎? –

相關問題