How to merge two JSONField fields

289 Views Asked by At

Postgres allows merging/concatenating two JSONB fields into one. Quoting the relevant Postgres docs:

jsonb || jsonb → jsonb - Concatenates two jsonb values.

As far as I can see, the Django ORM does not provide an operator for this type of concatenation. django.db.models.expressions.Combinable does not have a || operator.

django.contrib.postgres.search.SearchQueryCombinable has a || operator, but this class does not seem to apply here.

How can I merge two JSONFields using Django functions, but without evaluating the queryset?

1

There are 1 best solutions below

0
Stefan_EOX On BEST ANSWER

Since expressions usually are of the mixin class Combinable, we can use the _combine method on an F field and customize the operator to be ||. ExpressionWrapper is necessary because Django cannot infer the output_field of our customized combination.

from django.db import models
from django.db.models import ExpressionWrapper, F

class MyModel(models.Model):
    jsonfield1 = models.JSONField()
    jsonfield2 = models.JSONField()


MyModel.objects.annotate(
    concatenated_jsonfields=ExpressionWrapper(
        F("jsonfield1")._combine(F("jsonfield2"), "||", reversed=False),
        output_field=models.JSONField(),
    )
)