#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 django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. 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.