python.django.correctness.string-field-null-checks.string-field-must-set-null-true

Community Favorite
profile photo of semgrepsemgrep
Author
10,112
Download Count*

If a text field declares unique=True and blank=True, null=True must also be set to avoid unique constraint violations when saving multiple objects with blank values.

Run Locally

Run in CI

Defintion

rules:
  - id: string-field-must-set-null-true
    patterns:
      - pattern-inside: |
          class $M(...):
            ...
      - pattern-not: $F = django.db.models.CharField(..., unique=True, blank=True,
          null=True, ...)
      - pattern-not: $F = django.db.models.TextField(..., unique=True, blank=True,
          null=True, ...)
      - pattern-either:
          - pattern: $F = django.db.models.CharField(..., unique=True, blank=True, ...)
          - pattern: $F = django.db.models.TextField(..., unique=True, blank=True, ...)
    message: If a text field declares unique=True and blank=True, null=True must
      also be set to avoid unique constraint violations when saving multiple
      objects with blank values.
    languages:
      - python
    severity: ERROR
    metadata:
      category: correctness
      technology:
        - django
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]

Examples

string-field-null-checks.py

from django.db import models
from django.db.models import Model

class FakeModel(Model):
    #ruleid: no-null-string-field
    fieldOne = models.CharField(
        max_length=200,
        null=True)
    # ruleid: string-field-must-set-null-true
    fieldTwo = models.CharField(
        unique=True,
        blank=True,
        max_length=30
    )
    # ruleid: string-field-must-set-null-true
    fieldAAAAA = models.TextField(
        unique=True,
        blank=True,
        max_length=30
    )
    # ok: string-field-must-set-null-true
    fieldThree = models.CharField(
        unique=True,
        null=True,
        blank=True,
        max_length=100
    )
    # ok: string-field-must-set-null-true
    notText = models.IntegerField(
        max_value=255
    )

def fake(**kwargs):
    pass

def nope():
    # ok: string-field-must-set-null-true
    return fake(unique=True, blank=True)