Built-in support for natural-keys in model

Natural keys are a nice part of the serialization/fixture engine in django.

The bad part is that natural keys are not part of model APIs and thus they requires manual work to be done:

  • defining a custom model-manager with the get_by_natural_key method
  • defining the get_natural_key method in model

This is done without any assurance that the selected fields for natural key are unique for the model (because every piece of code should be handled manually).

Currently there is an app which tries to provide some ready-to-use code for this use case: django-natural-keys, which lacks support for partial unique constraints (aka: unique constraint with a condition) and is not very predictable when there are more than one unique field (also it brings as mandatory a dependency which is only used when interacting with rest framework).

I would like to know if there was a reason for not implementing the natural-key APIs in the base model?

I belive that it would be cool to have natural key handled by the Meta attribute of models by creating the appropriated methods on the default manager and on model class.
I feel that since natural-keys are already part of django serialization mechanism this would be a nice improvement to django, and I would like to hear if there are other people who belive this could be a valid improvement.

1 Like

This would have been added a long time ago, with many of the responsible devs no longer being active. The best way to find out would be to track down the original ticket and commit that added support, and any other natural-key-related tickets.

These are issues with the package which I think you’d be able to address there - it seems well-maintained enough, with a recent release.


To be honest, Django’s built-in serialization framework seems to have fallen a bit out of use, so improvements like your proposal won’t be of interest to many. Serialization for APIs is normally handled with DRF, or similar packages like ninja. Storing test/local data in fixtures tends to become a maintenance headache, as they need updating in line with migrations. Instead, I see most teams using factory functions.

Perhaps some efforts to improve the framework, like making natural keys a little easier to use, could be helpful. But I would like to hear input from others who actually use the serialization…

1 Like

Thanks for your candor @adamchainz . I was working on serializing fixtures (to use some amount of real data in the test suite) for a project that mostly uses DRF for our serialization and your message just saved me a lot of time from reimplementing the wheel.

Any chance of putting “Historical: Recommendation use DRF or Factory Functions” into the Django docs for the next version to steer users that direction? It might help reduce maintenance costs for the core team and help users as well. (Thanks!!)