2010-01-28 14 views
5

Tengo un modelos de Django que son algo así:de consulta para un campo ManyToMany con A través de Django

class Classification(models.Model): 
    name = models.CharField(choices=class_choices) 
    ... 

class Activity(models.Model): 
    name = models.CharField(max_length=300) 
    fee = models.ManyToManyField(Classification, through='Fee') 
    ... 

class Fee(models.Model): 
    activity = models.ForeignKey(Activity) 
    class = models.ForeignKey(Classification) 
    early_fee = models.IntegerField(decimal_places=2, max_digits=10) 
    regular_fee = models.IntegerField(decimal_places=2, max_digits=10) 

La idea es que habrá un conjunto de tarifas asociadas a cada par de actividad y clasificación. La clasificación es como Estudiante, Personal, etc.

Sé que la pieza funciona bien.

Luego, en mi solicitud, consulta para un conjunto de actividades con:

activities = Activity.objects.filter(...) 

que devuelve una lista de actividades. Necesito mostrar en mi plantilla esa lista de actividades con sus tarifas. Algo como esto:

Activity Name 
Student Early Price - $4 
Student Regular Price - $5 
Staff Early Price - $6 
Staff Regular Price - $8 

Pero no sé de una manera fácil de obtener esta información sin una consulta ser específico de las tasas objeto para cada par de actividad/clase.

yo esperaba que esto funcionaría:

activity.fee.all() 

Pero eso sólo devuelve el objeto de clasificación. ¿Hay alguna manera de obtener los Datos de Objeto de Cuota para el Par a través de las Actividades que ya he consultado?

¿O estoy haciendo esto completamente mal?

Respuesta

5

Considerando punta de michuk cambiar el nombre de "cuota" a la "clasificación":

nombre predeterminado para objetos Fee en modelo de actividad será fee_set. Así que con el fin de obtener sus precios, hacer esto:

for a in Activity.objects.all(): 
    a.fee_set.all() #gets you all fees for activity 

Hay una cosa, sin embargo, como se puede ver que va a terminar haciendo 1 SELECT en cada actividad objeto de honorarios, hay algunas aplicaciones que pueden ayudar con que, por ejemplo, django-batch-select hace solo 2 consultas en este caso.

1

En primer lugar creo que nombró mal su campo. Este:

fee = models.ManyToManyField(Classification, through='Fee') 

debería ser más bien que:

classifications = models.ManyToManyField(Classification, through='Fee') 

como ManyToManyField refiere a una lista de objetos relacionados.

En general, ManyToManyField, AFAIK, es solo un acceso directo django para permitir la búsqueda fácil de todos los objetos relacionados (Clasificación en su caso), con la tabla de asociación transparente para el modelo. Lo que desea es la tabla de asociación (Tarifa en su caso) no siendo transparente.

Así que lo que haría es eliminar el campo ManyToManyField de Activity y simplemente obtener todos los honorarios relacionados con la actividad. Y luego, si necesita una Clasificación para cada tarifa, obtenga la Clasificación por separado.

Cuestiones relacionadas