Skip to main content

LibCST-based linting rules for DRF serializers — detects ORM queries causing N+1

Project description

mitol-drf-lint

LibCST-based linting rules for Django REST Framework serializers. Detects Django ORM queries executed inside DRF serializer methods, which cause N+1 query bugs.

Rules

Rule Description
ORM001 Django ORM manager access (.objects.) inside a serializer method
ORM002 Related-manager queryset call (instance.children.filter() etc.) inside a serializer method

Installation

pip install mitol-drf-lint

Usage

# Check specific files
drf-lint path/to/serializers.py

# Check all serializers in a project
drf-lint $(find . -name "serializers.py" -not -path "*/migrations/*")

# Generate a baseline to suppress existing violations (for gradual rollout)
drf-lint --generate-baseline --baseline drf_lint_baseline.json path/to/serializers.py

# Subsequent runs ignore violations present in the baseline
drf-lint --baseline drf_lint_baseline.json path/to/serializers.py

Exit code is 0 when no new violations are found, 1 when violations are detected.

pre-commit Integration

In this repo (local)

- repo: local
  hooks:
    - id: drf-serializer-orm-check
      name: DRF Serializer ORM Check
      entry: drf-lint
      language: python
      files: "serializers\\.py$"

From other repos

- repo: https://github.com/mitodl/ol-django
  rev: <commit-sha-or-tag>
  hooks:
    - id: drf-serializer-orm-check

Suppressing individual violations

Add # noqa: ORM001 or # noqa: ORM002 at the end of the offending line, or # noqa to suppress all rules on that line:

def get_image(self, instance):
    item = instance.children.order_by("position").first()  # noqa: ORM002

How it works

The checker uses LibCST to parse Python source files into a concrete syntax tree and walks the tree looking for:

  1. Serializer classes: any class whose name ends in Serializer or that inherits from a class containing Serializer.
  2. Inside methods of those classes: any Call node matching ORM patterns.

ORM001 pattern: attribute chain containing .objects (Django model manager), e.g. User.objects.filter(...).

ORM002 pattern: queryset method call on a multi-level attribute access, e.g. instance.children.all(), instance.resource_prices.filter(...).

Methods inside inner classes (e.g. class Meta) are not checked.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mitol_drf_lint-2026.4.2.tar.gz (7.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mitol_drf_lint-2026.4.2-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file mitol_drf_lint-2026.4.2.tar.gz.

File metadata

  • Download URL: mitol_drf_lint-2026.4.2.tar.gz
  • Upload date:
  • Size: 7.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for mitol_drf_lint-2026.4.2.tar.gz
Algorithm Hash digest
SHA256 c8e4ba0e518f0f37016a00e9ed6b72e2d1645b750d79da695192a8ef49460c37
MD5 d7f65ef2362e08961a8ce55ea0b54353
BLAKE2b-256 7ff3a4f6c2556efd3605425be21f71c8b27a4cafebebb269875b607faaefb285

See more details on using hashes here.

File details

Details for the file mitol_drf_lint-2026.4.2-py3-none-any.whl.

File metadata

File hashes

Hashes for mitol_drf_lint-2026.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 dec795ab47ba0f983e13b2af19eb6842a6c6fd24c244fbd20be68a6211f21588
MD5 529b6a1cb6b2a96e045a7931496bdc88
BLAKE2b-256 595c0d25ae042b082a404eaef88ae8f177b2c5d570121f3bc575636e280a6016

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page