2011-10-27 24 views
6

tengo algunos modelos de Django, digoUso de `issubclass()` con modelos de Django

class Foo(models.Model): 
    class Meta: 
     abstract = True 

class Bar(Foo) 
    pass 

me gustaría ser capaz de encontrar todos los modelos que heredan de Foo, con el fin de realizar una tarea con ellos. Debe ser fácil, como

from django.db import models 
from myapp.models import Foo 

for model in models.get_models(): 
    if issubclass(model, Foo): 
     do_something() 

Por desgracia, esto no funciona, ya que issubclass(Bar, Foo) informes False, probablemente como resultado del funcionamiento interno de la metaclase Django que inicializa los modelos.

¿Hay alguna forma de comprobar si un modelo de Django es un descendiente de un modelo abstracto de Django?

Por favor, no sugiera pato escribir como la solución. En este caso, realmente me gustaría saber si existe una relación de subclase.

+0

Formulándome la misma pregunta ... Después de muchas pruebas e introspección de código, supongo que no parece posible, ya que los modelos abstractos son callables, y los objetos hijo no tienen ningún atributo o método que se ajuste a esto necesariamente. – Oleiade

+1

Parece extraño ... Acabo de crear una nueva aplicación django en un virtualenv, y su código está funcionando, mi 'do_something()' es simplemente un 'modelo de impresión' y funciona. resultado: . ¿Estás seguro de que tu problema proviene del resumen? FYI Estoy usando django 1.3.1 –

+1

También trabajando para mí en Django 1.3.1 – Brandon

Respuesta

0

tal vez algo como

subclasses = Foo.__subclasses__() 
for subclass in subclasses: 
    # we need to keep looking for subclasses of the subclasses 
    subclasses += subclass.__subclasses__() 
# sometimes we don't care about abstract classes 
concrete_subclasses = filter(lambda c: not c._meta.abstract, subclasses) 
1

El problema es cómo importar las clases. En lugar de:

from myapp.models import Foo 

uso:

from myproject.myapp.models import Foo 

para ver lo que es la forma correcta, se puede ver cómo Django es la importación de sus modelos con:

print models.get_models() 
+0

¿me puede explicar por qué hay un problema si importo usando 'myapp.models'? Entonces, si quiero escribir una aplicación reutilizable, ¿tengo que escribir import-things sin el nombre del proyecto, o estoy equivocado? – zambotn

0

Uso

Bar._meta.get_base_chain(Foo) 

para obtener una lista que describe la herencia cadena nce entre Foo y Bar.

Cuestiones relacionadas