2013-12-05 3 views
6

у меня есть 3 модели для списка дел приложения:Джанго получить все записи родственных моделей

class Topic(models.model) 
    user = models.ForeignKey(UserProfile) 
    lists = models.ManyToManyField(List) 

class List(models.model) 
    activities = models.ManyToManyField(Activity) 

class Activity(models.model) 
    activity = models.CharField(max_length=250) 

Это имеет смысл, когда пользователь выбирает тему, то список (подкатегория), который показывает все действия в этом списке.

Но как бы я эффективно запрос, такие вещи, как

  • Все мероприятия пользователя X (независимо тему или список)
  • Все мероприятия тему X для пользователя X (независимо от списков)

Должен ли я использовать select_related() в запросе, а не цитировать через связанные объекты, или есть более эффективный способ без цикла? (? Или я должен изменить свои модели)

ответ

9

Используйте синтаксис двойного подчеркивания для запроса по отношениям.

Все действия для пользователя:

Activity.objects.filter(list__topic__user=my_user) 

Все виды деятельности для пользователя для темы:.

Activity.objects.filter(list__topic=my_topic) 

(Обратите внимание, что в настоящее время эта тема для отдельного пользователя только не уверен, если это то, что вы mean: вы описываете пользователя , выбрав тему, которая не может произойти здесь. Потенциально ссылка из темы в UserProfile должна идти в другую сторону или быть многопользовательской.)

+0

Это обратная связь. –

+0

Nevermind, у меня есть замораживание мозга :) –

+0

Почему это работает для обратных отношений? Разве я не должен использовать что-то вроде list_set__topic? (Я просто не знаю об этой возможности) – jvannistelrooy

0

Дайте им родственные имена (это проще управлять):

class Topic(models.model) 
    user = models.ForeignKey(UserProfile, related_name = 'topics') 
    lists = models.ManyToManyField(List, related_name = 'topics') 

class List(models.model) 
    activities = models.ManyToManyField(Activity, related_name = 'lists') 

class Activity(models.model) 
    activity = models.CharField(max_length=250) 

Тогда вы можете сделать удивительные вещи:

user = UserProfile.objects.get(pk=1) # for example 
user.topics.all() # returns all topics 

topic = Topic.objects.get(pk=1) # for example 
topic.users.get(pk=1) # returns user 
lists = topic.lists.all() # returns List object instances QuerySet 

for list in lists: 
    list.activites.all() 

Handy Информация: https://docs.djangoproject.com/en/dev/ref/models/relations/

+0

'lists' будет набором запросов и не будет иметь атрибут' activity'. –

Смежные вопросы