#35729: How to serialize user profiles without natural keys?
--------------------------------+-----------------------------------------
Reporter: Jonas Dittrich | Type: Uncategorized
Status: new | Component: Uncategorized
Version: 5.1 | Severity: Normal
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+-----------------------------------------
We want to have a custom UserProfile that inherits from AbstractBaseUser
without the need to define a natural key. There should be a nice way to do
this.
Our custom UserProfile inherits from AbstractBaseUser. We don't have any
possible unique field combination that we could use as a `natural_key`.
(Our `USERNAME_FIELD` is not unique. It's an email that might be NULL for
multiple users)
When dumping data, we want to use `natural_foreign=True` and
`natural_primary=True` matching the
documentation recommendations, see
https://docs.djangoproject.com/en/5.1/topics/serialization/#natural-keys.
Now, `AbstractBaseUser` defines the `natural_key` function to return the
value of `USERNAME_FIELD` and there doesn't seem to be an alternative
implementation in our derived class.
Is there a way to dump our data using `natural_foreign=True` and
`natural_primary=True` without serializing the user profile with natural
keys?
What we tried so far:
- making natural_key just return `(pk,)`. This does not work. The pk of
the user profile is not serialized because the model defines `natural_key`
and django excludes the pk from the list of dumped fields when a
`natural_key` exists, see
https://github.com/django/django/blob/c6a4f853c7167c1001761dcff30d7a64690e8236/django/core/serializers/python.py#L37.
- overwriting `__getattribute__` on the user profile, raising an
`AttributeError` when `natural_key` is requested. M2M fields call
`hasattr` on the class, not on the instance which has the modified
`__getattribute__` function.
- trying to delete the `natural_key` function from our user profile class
using `del` and `delattr`. `hasattr` finds the function from the
superclass; our user profile does not define the `natural_key` function.
Basically the problem is that removing the `natural_key` function from the
child class violates Liskov's substitution principle.
In theory, we could `del AbstractBaseUser.natural_key` but this deeply
interferes with Django; we don't want to do that.
--
Ticket URL: <
https://code.djangoproject.com/ticket/35729>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.