We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Custom model managers and custom querysets let Django developers add extra methods to or modify the initial queryset for a model. Using these promotes the “don’t repeat yourself” (DRY) principle in software development and promotes reuse of common queries.
import datetime
from django.db import models
class TickerQuerySet(models.QuerySet):
def annotate_latest_price(self):
return self.annotate(
latest_price=TickerPrice.objects.filter(
ticker=models.OuterRef("pk")
)
.order_by("-close_date")
.values("price")[:1]
)
def prefetch_related_yesterday_and_today_prices(self):
today = datetime.datetime.today()
yesterday = today - datetime.timedelta(days=1)
return self.prefetch_related(
models.Prefetch(
"ticker_prices",
queryset=TickerPrice.objects.filter(
models.Q(close_date=today)
| models.Q(close_date=yesterday)
),
)
)
class TickerManager(models.Manager):
def get_queryset(self):
return TickerQuerySet(self.model, using=self._db)
class Ticker(models.Model):
symbol = models.CharField(max_length=50, unique=True)
objects = TickerManager()
class TickerPrice(models.Model):
ticker = models.ForeignKey(
Ticker, on_delete=models.CASCADE, related_name="ticker_prices"
)
price = models.DecimalField(max_digits=7, decimal_places=2)
close_date = models.DateField()
In the above code, we’ve created a custom queryset with some of the previously demonstrated queries as methods. We added this new queryset to our custom manager and overrode the default objects
manager on the Ticker
model with our custom manager. With the custom manager and queryset, we can do the following.
tickers_with_prefetch = (
Ticker.objects.all().prefetch_related_yesterday_and_today_prices()
)
tickers_with_latest_price = Ticker.objects.all().annotate_latest_price()
Instead of having to write the actual query for each of these examples, we call the methods defined in the custom queryset. This is especially useful if we use these queries in multiple places throughout the codebase.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.