This tip is particularly useful when you want to merge two or more querysets into a single queryset without losing
the capabilities of performing filter, count, distinct, etc. operations.
Consider the following models:
class Story(models.Model):
title = models.CharField(max_length=255)
content = models.TextField(blank=True)
category = models.ForeignKey(Category, related_name='stories')
author = models.ForeignKey(User, related_name='stories')
class Medium(models.Model):
name = models.CharField(max_length=30, unique=True)
stories = models.ManyToManyField(Story)Let’s say you want to display all the stories published in a specific Medium together with stories written by a
User using the Category django. Note that this User might have published stories in different Medium:
medium = Medium.objects.get(name='Django Blog')
user = User.objects.get(username='vitor')
django_stories = medium.stories.all()
vitor_stories = user.stories.filter(category__name='django')At this point we have two different querysets, one containing all the stories from a medium and other containing all the stories from a user using the django category.
The querysets can be merged like in the example below, using the | operator:
stories = django_stories | vitor_stories # merge querysetsAnd you still can perform queryset operations:
recent_stories = stories.distinct().order_by('-date')[:10]It’s important to note that the merge/combine operator | only works on querysets from the same model and before the
slicing it.
(Picture:
Django Tips #22 Designing Better Models
A Complete Beginner's Guide to Django - Part 2
How to Create Group By Queries With Django ORM
How to Extend Django User Model
How to Setup a SSL Certificate on Nginx for a Django Application
How to Deploy a Django Application to Digital Ocean