DJG104

Instantiating Django expressions with a dangerous template string literal.

This check looks at direct instantiations of the :

  • django.db.models.Func
  • django.db.models.Aggregate
  • django.db.models.Window
  • django.db.models.Expression
  • django.db.models.lookups.Transform

It will also look at calls to super().as_sql(), or self.as_sql() in classes which inherit from these types.

New classes to any of these types will also have their template attributes inspected.

Examples

from django.db.models import F, Func

queryset.annotate(field_lower=Func(F('field'), function='LOWER', template="'%(function)s'(%(expressions)s)"))

This inheritance example would also raise a warning:

class ConcatPair(Func):
    function = 'CONCAT'

    def as_mysql(self, compiler, connection, **extra_context):
        return super().as_sql(
            compiler, connection,
            function='CONCAT_WS',
            template="'%s'",
            **extra_context
        )

This child class would also raise a warning

class Example(Expression):
    function = 'EXAMPLE'
    template = "%(function)('%(special)s')"

Fixes

Remove the quotations from the expressions:

from django.db.models import F, Func

queryset.annotate(field_lower=Func(F('field'), function='LOWER', template="%(function)s(%(expressions)s)"))