2015-07-12 6 views
6

Für die folgende Modellgruppe (Foo, Bar) können Sie eine Kreuzvalidierungsregel wie die in der Bar.clean des folgenden Codeausschnitts bis zum Django erzwingen 1.7.Django 1.8.3 - Modellfeldvalidierung mit zugehörigem Objekt

Das gleiche Snippet löst einen RelatedObjectDoesNotExist Fehler in Django 1.8.3.

Was ist der neue und verbesserte Weg, um das gleiche Ergebnis in Django 1.8.3 zu erreichen?

(Ich habe den admin.py Code enthalten nur um zu zeigen, wie diese Modelle verwendet werden.)

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) 

Antwort

1

I habe eine einfache Ausgangsmodifikation zu Ihrem Code hinzugefügt

def clean(self): 
    print(self.__dict__) 

    if self.name + self.foo.name != 'FooBar': 
    raise ValidationError('Concatenation should be FooBar.') 

Die einfachen Druckanweisungen drucken das Bar-Objekt vor der Ausführung des Hauptcodes aus.

Jetzt habe ich den Code mit Django 1.8.x getestet und ich habe die Ausnahme bekam, wie Sie erwähnt dies ist das Ergebnis:

{'_state': <django.db.models.base.ModelState object at 0x7ff55cd30710>, 'id': None, 'foo_id': None, 'name': 'Bar 1'} 

Jetzt habe ich es wieder mit Django 1.7.x getestet und es funktioniert ok, ist das Ausgangsergebnis:

{'_foo_cache': <Foo: Foo object>, 'name': 'Bar 1', 'id': None, 'foo_id': None, '_state': <django.db.models.base.ModelState object at 0x7f731151c9e8>} 

Wie Sie die foo_id in None in beiden Fällen bemerkt haben, aber was macht die Magie ist das _foo_cache, was in Django 1.8

entfernt wurde

Der Ersatz, die ich vorschlagen kann, ist die Validierung in Forms

diese Änderungen vorgenommen bewegen: 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

Diese Selbstbeobachtung sehr nützlich war, Danke. Haben Sie eine Ahnung, warum Django-Entwickler die Möglichkeit, verwandte Objekte von einer model clean() -Methode zu entfernen, entfernen könnten, was ziemlich praktisch erscheint? –

Verwandte Themen