Mam 3 modele do aplikacji do listy:

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)

Ma to sens, gdy użytkownik wybiera temat, a następnie lista (podkategoria), która pokazuje wszystkie działania na tej liście.

Ale jak zrobiłbym efektywnie zapytać

  • Wszystkie działania użytkownika X (niezależnie od tematu lub listy)
  • Wszystkie działania tematu X dla użytkownika X (niezależnie od list)

Czy musiałbym użyć select_related() w zapytaniu i niż pętli przez pokrewne obiekty, czy jest bardziej wydajny bez zapętlenia? (Lub powinienem zmienić moje modele?)

8
jvannistelrooy 5 grudzień 2013, 13:06

2 odpowiedzi

Najlepsza odpowiedź

Użyj składni podwójnej podkreślenia do zapytania w zależności od relacji.

Wszystkie działania dla użytkownika:

Activity.objects.filter(list__topic__user=my_user)

Wszystkie działania dla użytkownika dla tematu:

Activity.objects.filter(list__topic=my_topic)

(Należy pamiętać, że obecnie tylko temat jest przeznaczony wyłącznie dla jednego użytkownika. Nie jestem pewien, czy to masz na myśli: opisujesz użytkownika wybierając temat, który nie mógł się tu zdarzyć. Potencjalnie link z tematu do UserProfile powinien iść na odwrót lub bądź manytomany.)

12
Daniel Roseman 5 grudzień 2013, 09:21

Daj im pokrewne imiona (łatwiej jest zarządzać):

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)

Wtedy możesz zrobić niesamowite rzeczy:

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()

Przydatne informacje: https://docs.djangoproject.com/en/dev/ref / modele / relacje /

1
McAbra 5 grudzień 2013, 09:21