2011-01-31 18 views
7

Tengo dos modelos Category y Entry. Hay otro modelo de ExtEntry que hereda de EntryDjango ForeignKey _set en un modelo heredado

class Category(models.Model): 
    title = models.CharField('title', max_length=255) 
    description = models.TextField('description', blank=True) 
    ... 

class Entry(models.Model): 
    title = models.CharField('title', max_length=255)  
    categories = models.ManyToManyField(Category) 
    ... 

class ExtEntry(Entry):  
    groups= models.CharField('title', max_length=255) 
    value= models.CharField('title', max_length=255) 
    ... 

Soy capaz de utilizar el Category.entry_set pero quiero ser capaz de hacer Category.blogentry_set pero no está disponible. Si esto no está disponible, entonces necesito otro método para obtener toda ExtEntry relacionados con un particular Category

EDITAR Mi objetivo final es tener un QuerySet de ExtEntry objetos

Gracias

Respuesta

3

necesito otro método para obtener toda ExtEntryrelated a una categoría en particular

Fácil:

ExtEntry.objects.filter(categories=my_category) 

¿Sabe usted si hay una manera de utilizar el _ID característica de un heredado

No sé si hay un directo para eso. No se menciona en la documentación.

Pero es posible obtener resultados similares con el select_related.

for e in category.entry_set.select_related('extentry'): 
    e.extentry # already loaded because of `select_related`, 
       # however might be None if there is no Extentry for current e 

Es posible seleccionar sólo las entradas que tiene ExtEntry:

for e in category.entry_set.select_related('extentry').exlude(extentry=None): 
    e.extentry # now this definitely is something, not None 

malo de la excluye es que genera consulta Terrybly ineficaz:

SELECT entry.*, extentry.* FROM entry 
LEFT OUTER JOIN `extentry` ON (entry.id = extentry.entry_ptr_id) 
WHERE NOT (entry.id IN (SELECT U0.id FROM entry U0 LEFT OUTER JOIN 
         extentry U1 ON (U0.id = U1.entry_ptr_id) 
         WHERE U1.entry_ptr_id IS NULL)) 

Así que mi hoja de vida sería : use ExtEntry.objects.filter() para obtener sus resultados. Las relaciones hacia atrás (object.something_set) son solo una conveniencia y no funcionan en todas las situaciones.

+0

Gracias ! esto soluciona mi problema ¿Sabes si hay una forma de usar la función _set de un modelo heredado? – neolaser

+0

si hay una relación de clave externa, puede usar model.ForeignKeyModel_set para devolver registros con esa relación – neolaser

+0

El único problema con esto es que devuelve el tipo Entry not ExtEntry para no tener acceso (directo) a los atributos adicionales del modelo ExtEntry . Lo siento por ser exigente jajaja, realmente aprecio la ayuda !! – neolaser

2

, consulte la documentación here para una explicación de cómo funciona esto

Básicamente, dado que puede obtener el elemento del modelo principal, debería poder obtener su hijo porque se crea un enlace implícito uno a uno.

La relación de herencia introduce enlaces entre el modelo hijo y cada uno de sus padres (a través de OneToOneField creado automáticamente).

lo tanto, debe ser capaz de hacer:

categories = Category.objects.all() 
for c in categories: 
    entries = c.entry_set.all() 
    for e in entries: 
     extentry = e.extentry 
     print extentry.value 

No está documentado que puedo ver, pero creo que, en general, el nombre de campo de uno-a-uno será un menor Versión de clase del nombre del modelo heredado.

+0

Gracias por la respuesta! Muy detallado y útil. Puedo ver cómo te estás acercando, mi problema es que tengo que devolver todo el conjunto. Y si tengo 10,000 Entry pero 3 ExtEntry, eso es un montón de bucles para encontrar 3 entradas ... Pero esto definitivamente funcionaría – neolaser

+0

Indeed. He mostrado para todas las categorías, pero recuerde que si solo se trata de una categoría específica, definitivamente descargue el ciclo externo. Me inclino a pensar que si solo necesitas tres objetos ExtEntry contra 1000 objetos, ¿por qué no solo tener campos en Entry con 'blank = True'? –

+0

ese ejemplo fue un poco extremo, estoy seguro de cuántos de cada uno tendré. incluso si fue de 10,000 v 5000 (todos en la misma categoría) es aún más procesamiento ... tal vez solo tenga que cop ti e ir con ese método ... – neolaser

0

El problema con el que se topa es porque Entry y ExtEntry están en tablas separadas. Esta puede ser la mejor solución para usted, pero debe tenerlo en cuenta cuando elija usar la herencia de tablas múltiples.

Algo así como category.entry_set.exclude(extentry=None) debería funcionar para usted.

Cuestiones relacionadas