Запрос на поле ManytoMany с помощью Through в Django - PullRequest
6 голосов
/ 28 января 2010

У меня есть модели в Джанго, которые выглядят примерно так:

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)

Идея заключается в том, что с каждой парой деятельности и классификации будет установлен набор сборов. Классификация: студент, персонал и т. Д.

Я знаю, что эта часть работает правильно.

Затем в моем приложении я запрашиваю набор действий с:

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

, который возвращает список действий. Мне нужно отобразить в моем шаблоне список видов деятельности с их тарифами. Примерно так:

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

Но я не знаю простого способа получить эту информацию без специального запроса get объекта Fees для каждой пары вид деятельности / класс.

Я надеялся, что это сработает:

activity.fee.all()

Но это просто возвращает объект классификации. Есть ли способ получить данные об объекте комиссии для пары через действия, которые я уже запросил?

Или я делаю это совершенно неправильно?

Ответы [ 2 ]

6 голосов
/ 29 января 2010

Учитывая подсказку Мичука переименовать "плату" в "классификацию":

Имя по умолчанию для объектов Fee в модели Activity будет fee_set. Поэтому, чтобы узнать цены, сделайте следующее:

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

Есть одна вещь, хотя, как вы можете видеть, в конечном итоге вы сделаете 1 SELECT для каждого объекта деятельности за плату, есть несколько приложений, которые могут помочь с этим, например, django-batch-select делает только 2 запроса в этом случае.

2 голосов
/ 29 января 2010

Прежде всего, я думаю, что вы назвали свое поле неправильно. Это:

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

должно быть скорее:

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

, поскольку ManyToManyField ссылается на список связанных объектов.

В общем, ManyToManyField, AFAIK, является всего лишь ярлыком django, позволяющим легко извлекать все связанные объекты (классификация в вашем случае), а таблица ассоциаций прозрачна для модели. То, что вы хотите, это таблица ассоциации (плата в вашем случае) не быть прозрачным.

Итак, я бы удалил поле ManyToManyField из Activity и просто получил все сборы, связанные с этим действием. И затем, если вам нужна классификация для каждого сбора, получите классификацию отдельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...