Pylint Django Plugin
Pylint-Django is a Pylint plugin designed to help Pylint understand the intricacies of the Django web framework. It provides specific checkers for Django models, forms, admin, and other components, catching common Django-related issues that a standard Pylint run would miss. The current version is 2.7.0, and it generally releases new versions to support new major releases of Pylint or Django, typically a few times a year.
Warnings
- breaking Pylint-Django v2.6.1 and newer dropped support for Python 3.7 and 3.8. Additionally, it requires Pylint 3.0 or higher.
- breaking Pylint-Django v2.7.0 added support for Pylint 4.0.0+. Older versions of `pylint-django` (before 2.7.0) are not compatible with Pylint 4.x and will likely cause crashes or incorrect analysis.
- gotcha The `pylint-django` plugin must be explicitly loaded by Pylint using the `--load-plugins pylint_django` CLI argument or by adding `load-plugins=pylint_django` to your `.pylintrc` or `pyproject.toml` configuration.
- gotcha When running Pylint outside of a Django project's `manage.py` command (e.g., directly on files or within a CI pipeline), you must set the `DJANGO_SETTINGS_MODULE` environment variable to a valid Django settings file for `pylint-django` to properly analyze models and other Django components.
Install
-
pip install pylint-django pylint django
Imports
- pylint_django
pylint --load-plugins pylint_django <your_django_app_path>
Quickstart
import os
import subprocess
import tempfile
import shutil
# Create a temporary directory to simulate a Django app structure
with tempfile.TemporaryDirectory() as temp_dir:
app_dir = os.path.join(temp_dir, "myapp")
os.makedirs(app_dir)
# Create a dummy models.py that pylint-django can analyze
models_code = '''
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
# pylint-django will check ForeignKey attributes, e.g., missing related_name
author = models.ForeignKey(Author, on_delete=models.CASCADE)
class Meta:
ordering = ['title']
def __str__(self):
return self.title
'''
models_file_path = os.path.join(app_dir, "models.py")
with open(models_file_path, "w") as f:
f.write(models_code)
print(f"Created temporary Django app file at: {models_file_path}")
# Create a minimal settings.py required for Django's ORM and app loading
settings_module_path = os.path.join(temp_dir, "settings.py")
with open(settings_module_path, "w") as f:
f.write('''
INSTALLED_APPS = ['myapp']
SECRET_KEY = 'insecure-key-for-testing'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
}
}
''')
# Set DJANGO_SETTINGS_MODULE environment variable for Pylint's context
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
print("Running Pylint with pylint-django loaded...")
try:
# Execute pylint from the temporary directory to correctly pick up settings.py
result = subprocess.run(
[
"pylint",
"--load-plugins",
"pylint_django",
"--disable=all", # Disable default Pylint checks for clearer output
"--enable=django-model-checks,django-form-checks,django-admin-checks,django-template-checks,django-other-checks", # Enable specific pylint-django checkers
"--rcfile=NONE", # Ignore user's pylintrc for consistent results
models_file_path # Target file for linting
],
capture_output=True,
text=True,
check=False, # Do not raise exception for non-zero exit codes (linting errors/warnings)
cwd=temp_dir # Run subprocess in the temporary directory
)
print("\n--- Pylint Output ---")
print(result.stdout)
if result.stderr:
print("\n--- Pylint Errors (stderr) ---")
print(result.stderr)
print("--- End Pylint Output ---")
except FileNotFoundError:
print("Error: 'pylint' command not found. Please ensure Pylint and pylint-django are installed.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
# Clean up the environment variable
del os.environ['DJANGO_SETTINGS_MODULE']