﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
28385	deserializers ignore natural keys when primary key has a default value	Daniel Knell	nobody	"{{{
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
}}}
([https://github.com/django/django/blob/169c3b3e07829d9ffa409b6eb5c1094d8ef918a8/django/core/serializers/base.py#L223 source on GitHub])

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
}}}

"	Bug	new	Core (Serialization)	1.11	Normal				Accepted	0	0	0	0	1	0
