Skip to main content

leukeleu-django-gdpr

Installation

pip install leukeleu-django-gdpr

Add to INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    'leukeleu_django_gdpr',
    # ...
]

Configuration

By default, the gdpr management command will write gdpr.yml to settings.BASE_DIR.

To change the output directory (without changing settings.BASE_DIR) add DJANGO_GDPR_YML_DIR to your settings:

DJANGO_GDPR_YML_DIR = os.path.join(BASE_DIR, 'docs')

Usage:

On first run, leukeleu-django-gdpr will generate a gdpr.yml file with a models list. This is a list of models in your project, each containing a list of fields.

./manage.py gdpr

A file gdpr.yml is created in the project root directory. It should be added to version control. Each model in the models list has the following structure:

models:
  auth.User:
    name: User
    fields:
      username:
        name: Username
        description: String (up to %(max_length)s)
        help_text: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
          only.
        required: true
        pii: null
      first_name:
        name: First Name
        description: String (up to %(max_length)s)
        help_text: ''
        required: false
        pii: null

Leukeleu-django-gdpr adds the pii: null to all fields. The objective is to replace all those null values with the correct boolean value; pii: true if the field represents PII data, pii: false otherwise.

When run again, leukeleu-django-gdpr will persist those values, allowing you to work your way to eliminating all pii: nulls.

Leukeleu-django-gdpr outputs counts of the pii: values when run:

./manage.py gdpr
Checking...
No PII set     48
PII True       1
PII False      0

Run with --check to make the command exit with exit code 1 if 'No PII set' > 0 (the yaml file will still be generated/updated).

You can prevent leukeleu-django-gdpr from writing (back) to the yaml file by running with the --dry-run flag.

Excluding/including

To exclude apps, models or fields from this process altogether, list them in the exclude: list in the yaml file. Each item is a regex which should match an object's string representation in the following formats;

  • for apps: the app's label, e.g. auth.
  • for models: the model's label, e.g. auth.Permission
  • for fields: the model's label followed by . followed by the field's name, e.g. auth.User.username.

Keep in mind that the items in the list are considered to be regexes which should fully match the object's string representation.

Default excludes

By default, leukeleu-django-gdpr excludes fields of the following types:

  • AutoField
  • UUIDField
  • BooleanField
  • RelatedField

and the following apps:

  • django.contrib.admin
  • django.contrib.contenttypes

If you still want to include a field/model that would be excluded this way, you can put an item in the include: list in the yaml file:

include:
- clients\.Client\.external_epd_uuid
- accounts\.Profile\.is_pregnant
- admin\.LogEntry

Proxy models are always excluded. They are the same as the model they proxy, so there is no benefit in including them.

Anonymizing data

Leukeleu-django-gdpr comes with a anonymize management command, that anonymizes all PII fields in the database.

It is meant to be used in development only. It requires an additional dependency and setting DEBUG = True.

pip install leukeleu-django-gdpr[anonymize]
./manage.py anonymize

This command uses the gdpr.yaml file to anonymize all fields marked as PII in the database.

To change the configuration, you can create a subclass of BaseAnonymizer:

Note that anonymizer functions should either conform to the leukeleu_django_gdpr.anonymize.AnonymizerFunction protocol or be functions that do not need to take any arguments.

# some_file.py

fake = Faker(["nl-NL"])

def custom_anonymizer(obj: Model, field: Field):
    return getattr(obj, field.name)[:4]

class Anonymizer(BaseAnonymizer):
    # Exclude rows
    # Default: superusers and staff users are excluded
    extra_qs_overrides = {
        "app.Model": Model._base_manager.exclude(some_field=...),
        ...
    }

    # Specify fake data for a field
    # Default: user's first_name and last_name are filled with random first/last names
    extra_field_overrides = {
        "app.Model.some_field": fake.word,
        "app.Model.some_other_field": lambda: "same value for every cell",
        ...
    }
    
    # Specify the fake data used for a field type
    # Use for custom fields or to overwrite defaults
    # Default: django builtin fields have "sensible" defaults
    extra_fieldtype_overrides = {
        "CustomPhoneNumberField": fake.phone_number,
      
        # Also specify a unique variant (append with ".unique")
        "CustomPhoneNumberField.unique": fake.unique.phone_number,
        
        # Use functools.partial to set arguments for simple functions
        "CustomRegionField": partial(fake.words, nb=4),

        # You can also use full custom functions for more complex behaviour
        "ImageHash": custom_anonymizer,
        ...
    }

    # Exclude fields
    # Default: no fields are excluded
    excluded_fields = [
        "app.SomeModel.some_field",
        ...
    ]

Then add this setting to your settings file:

DJANGO_GDPR_ANONYMIZER_CLASS = "location.to.custom.Anonymizer"

Checks

Leukeleu-django-gdpr adds a gdpr.I001 check to the check command. This check will fail if there are any pii: null values in the yaml file. To run the check, run:

./manage.py check

CI/CD

Run the check command to make a (scheduled) CI/CD task fail if there are unclassified fields, which can happen if someone adds a field to a model but forgets to classify it in the gdpr.yml.

Release files for leukeleu-django-gdpr 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for leukeleu-django-gdpr 2.2.0
File Size Uploaded
leukeleu_django_gdpr-2.2.0.tar.gz 27.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for leukeleu-django-gdpr 2.2.0
File Interpreter ABI Platform
leukeleu_django_gdpr-2.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 72.3 kB

Release files / leukeleu_django_gdpr-2.2.0.tar.gz

Download URL leukeleu_django_gdpr-2.2.0.tar.gz
Size 27.9 kB
Tags Source
SHA-256 checksum
How to use checksums
364afe576f11cbbb9d4e800a781cc225827c2ac378c769b62ebbcb0b9101861f
BLAKE2b-256 checksum
How to use checksums
d3b942a822b50362856ca28fc83379933ce24a5150d80b36d502195cd524dd31
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 17, 2026.

Transparency log

Release files / leukeleu_django_gdpr-2.2.0-py3-none-any.whl

Download URL leukeleu_django_gdpr-2.2.0-py3-none-any.whl
Size 44.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
036e8c975e4ee823e5bd6a17ffc9b26f2f27e47f9359bc40984c60a6b4071a32
BLAKE2b-256 checksum
How to use checksums
b6c52e03b60dd7525189b8c2b2e8fe683a2c92790bbedc8ed056d962d3c06fb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.2.0 This release

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page