Django has a many built-in database functions and a documented Func
API for writing your own.
Whilst writing a custom Func
subclass may sometimes be necessary, I learnt that there’s many cases when you can instantiate Func
with the necessary arguments to get what you need. For example, take the following model.
from django.contrib.postgres.fields import ArrayField
from django.db import models
class Post(models.Model):
tags = ArrayField(models.CharField(max_length=200))
Making use of the array_shuffle
Postgres Array Function and an annotation, each of the post’s tags are in a randomised order.
from django.db.models import F, Func
posts = Post.objects.annotate(
tags_shuffle=Func(F("tags"), function="ARRAY_SHUFFLE"),
)
A second, slightly more contrived example.
from django.db import models
class Post(models.Model):
published_year = models.IntegerField()
published_month = models.IntegerField()
published_day = models.IntegerField()
This time using the make_date
Postgres’ Date/Time Function to get a date
object from the post’s published values.
from django.db.models import DateField, F, Func
posts = Post.objects.annotate(
published_date=Func(
F("published_year"),
F("published_month"),
F("published_day"),
output_field=DateField(),
function="MAKE_DATE",
)
)