2010-08-20 3 views
6

Ich hatte vorher Modelle wie folgt aus:Django inlinemodeladmin Validierung - aber mit einer allgemeinen Beziehung

class AssemblyAnnotation(models.Model): 
    assembly = models.ForeignKey(Assembly) 
    type = models.ForeignKey(AssemblyAnnotationType) 
    ... 
    def clean(self): 
     from django.core.exceptions import ValidationError 
     if not self.type.can_annotate_aliases and self.assembly.alias_of_id is not None: 
      raise ValidationError('The selected annotation type cannot be applied to this assembly.') 

Der Effekt war, ein neues AssemblyAnnotation (über eine Inline-Anlage) konnte nur eine Teilmenge von Werten für seine type-Attribut , abhängig von der übergeordneten Assembly.

Das hat super funktioniert.

Nun hat es kommen Zeit, diese Anmerkungen auf andere Objekte anzuwenden, die etwas anders sind:

class ObjectAnnotation(models.Model): 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey() 
    type = models.ForeignKey(AssemblyAnnotationType) 
    ... 
    def clean(self): 
     from django.core.exceptions import ValidationError 
     if self.content_type == ContentType.objects.get_for_model(Assembly): 
      if not self.type.can_annotate_aliases and self.content_object.alias_of_id is not None: 
       raise ValidationError('The selected annotation type cannot be applied to this assembly.') 

Wie Sie sehen können, möchte ich die gleichen Regeln angewendet. Es gibt jedoch ein Problem. Die GenericInline, die ich jetzt verwende, legt nicht den self.content_type fest, bevor meine clean() -Methode ausgeführt wird.

Gibt es einen Weg um dies zu umgehen? Mache ich das falsch?

Danke für die Hilfe.

Antwort

0

Würde die rechte Seite keine Liste in if self.content_type == ContentType.objects.get_for_model(Assembly): zurückgeben?

Ich würde denken, Sie if self.content_type in ContentType.objects.get_for_model(Assembly):

+0

Nein, get_for_model [gibt ein einzelnes ContentType-Objekt zurück] (https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.models.ContentTypeManager.get_for_model). Wie auch immer, das ist nicht das Problem. Das Problem ist, dass GenericInline den Inhaltstyp vor dem Aufruf von clean() nicht festlegt. –

0

Ich verwende das gleiche wie Sie tun müssen und es funktioniert wie espected. Hier ist mein Code:

in den Modellen:

class GroupFlagIntermediate(models.Model): 
    group_flag = models.ForeignKey(GroupFlag, related_name='flag_set') 
    content_type = models.ForeignKey(ContentType, verbose_name='Flag Type') 
    flag_pk = models.CharField('Flag PK', max_length=100, blank=True, default='') 
    flag = generic.GenericForeignKey('content_type', 'flag_pk') 

    def clean(self): 
     from django.core.exceptions import ValidationError 
     if not self.is_valid_flag(self.content_type.model_class()): 
      raise ValidationError('The selected flag is not a real Flag.') 

Und im Admin:

class GroupFlagIntermediateInline(admin.TabularInline): 
    model = GroupFlagIntermediate 

class GroupFlagAdmin(admin.ModelAdmin): 
    list_display = ('name', ...) 
    inlines = [GroupFlagIntermediateInline] 

admin.site.register(GroupFlag, GroupFlagAdmin) 

Nach einigen Tests, fand ich, dass die content_type und object_id (flag_pk in meinem Fall) Felder sind gesetzt vor dem clean() call, aber die GenericForeignKey (flag in meinem Fall) nicht.