MultipleObjectsReturned with get_or_create

django, python-2.7

Solution

As the name implies, `get_or_create` `model.objects.get()`s or `model.objects.create()`s.

It's conceptually equivalent to:

try:
   model.objects.get(pk=1)
except model.DoesNotExist:
   model.objects.create(pk=1)

The source is where you find definitive answers to these types of questions. Hint: search `def get_or_create`. As you can see, this function only catches `DoesNotExist` in the try/except.

def get_or_create(self, **kwargs):
    """
    Looks up an object with the given kwargs, creating one if necessary.
    Returns a tuple of (object, created), where created is a boolean
    specifying whether an object was created.
    """
    assert kwargs, \
            'get_or_create() must be passed at least one keyword argument'
    defaults = kwargs.pop('defaults', {})
    lookup = kwargs.copy()
    for f in self.model._meta.fields:
        if f.attname in lookup:
            lookup[f.name] = lookup.pop(f.attname)
    try:
        self._for_write = True
        return self.get(**lookup), False
    except self.model.DoesNotExist:

Problem

I'm writing a small django command to copy data from a json API endpoint into a Django database. At the point I actually create the objects, with `obj, created = model.objects.get_or_create(**filters)`, I am getting a `MultipleObjectsReturned` error. This is surprising to me, because my understanding of `get_or_create` is that if I try to create an object that already exists, it will just 'get' it instead. I'm not certain about the integrity of the database I'm cloning, but even if there are multiple identical objects in it, when I load them into my local Django database, shouldn't get_or_create make it so that I never get more than one copy? Can anybody explain this? I'm happy to give more specifics, I just didn't want to bog the reader down.

Original source

Related problems