#28385: deserialisers ignore natural keys when primary key has a default value
------------------------------------------------+------------------------
Reporter: Daniel Knell | Owner: nobody
Type: Bug | Status: new
Component: Core (Serialization) | Version: 1.11
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 1
UI/UX: 0 |
------------------------------------------------+------------------------
https://github.com/django/django/blob/master/django/core/serializers/base.py#L223
{{{
def build_instance(Model, data, db):
"""
Build a model instance.
If the model instance doesn't have a primary key and the model
supports
natural keys, try to retrieve it from the database.
"""
obj = Model(**data)
if (obj.pk is None and hasattr(Model, 'natural_key') and
hasattr(Model._default_manager, 'get_by_natural_key')):
natural_key = obj.natural_key()
try:
obj.pk =
Model._default_manager.db_manager(db).get_by_natural_key(*natural_key).pk
except Model.DoesNotExist:
pass
return obj
}}}
this causes loaddata to fail on second attempt when using natural keys and
uuid primary keys as pk is set.
{{{
class FooManager(models.Manager):
def get_by_natural_key(self, name):
return self.get(name=name)
class Foo(DateTimeMixin, models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4,
editable=False)
name = models.CharField(max_length=100, unique=True)
objects = FooManager()
def natural_key(self):
return (self.name,)
}}}
checking the primary key was not actually set seems to fix things:
{{{
def build_instance(Model, data, db):
obj = Model(**data)
pk = data.get(Model._meta.pk.name, None)
if (pk is None and hasattr(Model, 'natural_key') and
hasattr(Model._default_manager, 'get_by_natural_key')):
natural_key = obj.natural_key()
try:
obj.pk =
Model._default_manager.db_manager(db).get_by_natural_key(*natural_key).pk
except Model.DoesNotExist:
pass
return obj
import django.core.serializers.base
django.core.serializers.base.build_instance = build_instance
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/28385>
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 post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/054.07206c2c1fa2bd89bb2d9cfe12c34590%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.