Django filter through multiple fields in a many-to-many intermediary table

26,195

Solution 1

Now, I want to filter all videos which have a specific format, AND the status code for that format is 10 (ready to use). How can I do that? (assuming that f is the format)

The code that you posted does exactly what you want:

Video.objects.filter(media__formats=f, media__mediaformat__status=10)

This is documented in the filter() documentation:

Multiple parameters are joined via AND in the underlying SQL statement.

Solution 2

You can chain the filters together for an "AND" construct.

Videos where the format is f AND the format's status is 10

Video.objects.filter(media__formats=f).filter(media__mediaformat__status=10)

Solution 3

Probably not relevant for the OP, but might be for others like me who found this thread while searching for the right answer.

Ludwik got it right, but the section in the documentation that explains all of this, as well as how to do excludes, is in the queries documentation.

Note that splitting the filter into two filter calls like Chris suggested will give you the exact opposite result: it will search for a video that has a media format f and that has a media format, not necessarily the same media format, with a status of 10.

Share:
26,195

Related videos on Youtube

inefavel
Author by

inefavel

Updated on July 09, 2022

Comments

  • inefavel
    inefavel over 1 year

    I have the following models in my django project:

    class Video(models.Model):
        media = models.ForeignKey(Media)
    
    class Media(models.Model):
        title = models.CharField(max_length=255)
        formats = models.ManyToManyField(Format,through='MediaFormat',related_name='media',blank=True)
    
    class Format(models.Model):
        title = models.CharField(max_length=50)
    
    class MediaFormat(models.Model):
        status = models.IntegerField()
        format = models.ForeignKey(Format)
        media = models.ForeignKey(Media)
    

    Now, I want to filter all videos which have a specific format, AND the status code for that format is 10 (ready to use). How can I do that? (assuming that f is the format):

    f = Format.objects.get(pk=3)
    

    I'm tempted to use:

    Video.objects.filter(media__formats=f, media__mediaformat__status=10)
    

    But then, that would return all videos that matches both of these assumptions:

    • a) contain that specific format, and
    • b) contain any format with the status of 10

    How am I supposed to filter only those who have that specific format in a status code of 10?

    thank you!

    • AncientSwordRage
      AncientSwordRage almost 9 years
      FYI if you want to OR two query sets, I beleive you use | between the querysets. Not sure how helpful this is to OP but it should help others who come here.
  • jarmod
    jarmod over 10 years
    Not sure how that is different to the OP's suggestion: Video.objects.filter(media__formats=f, media__mediaformat__status=10)
  • klis87
    klis87 about 7 years
    Actually it is different from OP suggestion, please look at docs.djangoproject.com/en/1.10/topics/db/queries/… for your reference