Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django get all records of related models

I have 3 models for a to-do list app:

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)

This makes sense when a user selects a Topic, then a List (sub-category), which shows all activities on that list.

But how would I efficiently query things like

  • All activities of user X (regardless topic or list)
  • All activities of topic X for user X (regardless of lists)

Would I need to use select_related() in the query and than loop trough the related objects, or is there a more efficient way without looping? (Or should I change my models?)

like image 276
JacobF Avatar asked Dec 05 '13 09:12

JacobF


People also ask

How do you get a related name on Django?

The related_name attribute specifies the name of the reverse relation from the User model back to your model. If you don't specify a related_name, Django automatically creates one using the name of your model with the suffix _set. Explanation: Illustration of related_name=”name” using an Example.

How do you query a many to many relationship in Django?

When querying many-to-many relationships, avoid using multiple filter() methods, make use of Q() objects instead. You can check the SQL query of a QuerySet with str(queryset. query) . Check the performance of recently executed SQL queries with django.

What is a QuerySet?

A QuerySet represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT .


1 Answers

Use the double-underscore syntax to query across relationships.

All activities for user:

Activity.objects.filter(list__topic__user=my_user)

All activities for user for a topic:

Activity.objects.filter(list__topic=my_topic)

(Note that currently a Topic is for a single user only. Not sure if that's what you mean: you describe a user selecting a topic, which couldn't happen here. Potentially the link from Topic to UserProfile should go the other way, or be a ManyToMany.)

like image 63
Daniel Roseman Avatar answered Oct 06 '22 14:10

Daniel Roseman