#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.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070191b42a92d9-d24703aa-4184-4009-bd45-00cb510d9b1e-000000%40eu-central-1.amazonses.com.

Reply via email to