Opened 3 months ago

Closed 3 months ago

#35729 closed New feature (invalid)

How to serialize user profiles without natural keys?

Reported by: Jonas Dittrich Owned by:
Component: contrib.auth Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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.

Change History (1)

comment:1 by Natalia Bidart, 3 months ago

Component: Uncategorizedcontrib.auth
Resolution: invalid
Status: newclosed
Type: UncategorizedNew feature
Version: 5.1dev

Hello Jonas, thank you for your ticket!

This report seems better suited to be a support request. The best place to get answers to your issue is using any of the user support channels from this link.

Since the goal of this issue tracker is to track issues about Django itself, and this report is about how to use Django for a specific niche need, I'll be closing this ticket as invalid following the ticket triaging process. If, after debugging or further conversations in the forum, you find out that this is indeed a bug in Django, please re-open with the specific details and please be sure to include a small Django project to reproduce or a failing test case.

Note: See TracTickets for help on using tickets.
Back to Top