The PrivacyMeta object

A model needs to be registered with gdpr-assist in order to use any of the anonymisation or export functionality.

The PrivacyMeta object tells gdpr-assist which fields are private, and what to do with them.

Registering automatically

If you define a class called PrivacyMeta within your model, gdpr-assist will automatically detect and register your model.

An instance of your PrivacyMeta class will then be available on the attribute _privacy_meta, the same way a standard Meta class works.

For example:

class Comment(models.Model):
    name = models.CharField(max_length=255, blank=True)
    age = models.IntegerField(null=True, blank=True)
    message = models.TextField()

    class PrivacyMeta:
        fields = ['name', 'age']

# The following statements are true:
assert(not hasattr(Comment, 'PrivacyMeta')
assert(hasattr(Comment, '_privacy_meta')
assert(Comment._privacy_meta.fields == ['name', 'age']

Registering manually

Sometimes you will want to define your PrivacyMeta class somewhere other than on the model - for example when you want to be able to export or anonymise a third-party object, or if you have a particularly complex privacy meta definition and want to store it in a separate file for clarity.

The gdpr_assist.register(<ModelClass>, [<PrivacyMetaClass>]) function will let you manually register the model with an optional PrivacyMeta class.

For example:

from django.contrib.auth.models import User

class UserPrivacyMeta:
    fields = ['first_name', 'last_name', 'email']

gdpr_assist.register(User, UserPrivacyMeta, gdpr_default_manager_name="objects_anonymised")

If you omit the privacy meta class, one will be generated for you with the default attributes.

Note that gdpr_default_manager_name is optional and by default objects will be cast to a PrivacyManager, except in the case of Models in which their manager users use_in_migrations, as the User example above does. In these cases a alternate name must be provided and user for queryset anonymisation in order not to create migrations for third parties. Model.anonymisable_manager() can also be used to access the PrivacyManager regardless of gdpr_default_manager_name.

Attributes

The PrivacyMeta object can have the following attributes:

can_anonymise = Boolean

default: True

Whether or not gdpr-assist is used to anonymise the data for this model, if False, you can still search and export using gdpr-assist.

fields = [...]

List of the names of fields which contain personal information.

These will be the ones which are anonymised; other fields will be unmodified.

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)

    class PrivacyMeta:
        fields = ['name']

anonymise_<field_name>(self, instance)

Custom function to anonymise the named field, for when the standard anonymisers won’t produce the desired result. This should also be used for custom field types.

Field name must appear in the fields list.

It should not return a value; instead it should operate directly on the instance.

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)

    class PrivacyMeta:
        def anonymise_name(self, instance):
            instance.name = 'Anon'

search_fields = [...]

List of fields to examine when searching for a value in the personal data tool in the admin site.

These field names will be used to build case-insensitive exact matches unless the field name contains a double underscore, __. For example:

  • name will create a filter of name__iexact=term
  • name__icontains will create a filter of name__icontains=term
  • person__name will create a filter of person__name=term

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)

    class PrivacyMeta:
        search_fields = ['name__icontains']

qs = search(self, value)

Function called by the personal data tool in the admin site, to search the model for the value.

The argument self will be a reference to the PrivacyMeta instance.

The default function will use search_fields, but this can be overridden to perform a custom search.

Should return a queryset (or iterable of objects).

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)

    class PrivacyMeta:
        def search(self, value):
            return self.model.objects.filter(name=value.lower())

export_fields = [...]

List of fields to export. By default will export all fields.

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)

    class PrivacyMeta:
        export_fields = ['name']

export_exclude = [...]

List of fields to not export. By default will exclude foreign keys and many to many fields.

If a field is specified in both export_fields and export_exclude, it will be excluded.

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)
    post_count = models.IntegerField(default=0)

    class PrivacyMeta:
        export_exclude = ['post_count']

export_filename = None

The filename to use for this model when exporting records from it. This should include the .csv extension, eg export_filename = 'user_records.csv'

If not set, it will default to <app_name>.<object_name>.csv, eg my_app.MyModel.csv

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)

    class PrivacyMeta:
        export_filename = 'my_model.csv'

data = export(self, instance)

Function called by the personal data tool in the admin site, to export a model instance.

By default will export all fields specified in export_fields and not excluded by export_exclude. They will all be cast to a string.

The default exporter cannot export foreign keys or many to many fields.

Should return a dict.

Example:

class MyModel(models.Model):
    name = models.CharField(max_length=255)

    class PrivacyMeta:
        def export(self, instance):
            return {
                'name': instance.name,
                'lower': instance.lower(),
            }