2010-08-20 7 views
6

Yo antes tenía modelos como este:Django inlinemodeladmin validación - pero con una relación genérica

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.') 

El efecto era, un nuevo AssemblyAnnotation (unido a través de una línea) sólo podría haber un subconjunto de valores para que de atributo type , dependiendo de la Asamblea padre.

Esto funcionó de maravilla.

Ahora, ha llegado el momento de aplicar estas anotaciones a otros objetos que son ligeramente diferentes:

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.') 

Como se puede ver, yo quiero las mismas reglas que se aplican. Sin embargo, hay un problema. El GenericInline que ahora estoy utilizando no establece self.content_type antes de que se ejecute mi método clean().

¿Hay alguna forma de evitar esto? ¿Estoy haciendo esto mal?

Gracias por la ayuda.

Respuesta

0

¿No sería el lado derecho devolver una lista en if self.content_type == ContentType.objects.get_for_model(Assembly):?

yo creo que tendría que hacer if self.content_type in ContentType.objects.get_for_model(Assembly):

+0

No, get_for_model [devuelve un solo objeto ContentType] (https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.models.ContentTypeManager.get_for_model). De todos modos, ese no es el problema. El problema es que GenericInline no establece content_type antes de llamar a clean(). –

0

estoy usando el mismo que usted y funciona como pensábamos. Aquí está mi código:

en los modelos:

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.') 

Y en la parte administrativa:

class GroupFlagIntermediateInline(admin.TabularInline): 
    model = GroupFlagIntermediate 

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

admin.site.register(GroupFlag, GroupFlagAdmin) 

Después de algunas pruebas, he encontrado que los content_type y object_id (flag_pk en mi caso) los campos son antes de la llamada a clean(), pero el GenericForeignKey (flag en mi caso) no.

Cuestiones relacionadas