Greg
Greg

Reputation: 47164

Django - get_or_create not working

can you help me understand why this code causes a duplicate entry (IntegrityError)?

I'm on Django 1.2.

(row, is_new) = MyModel.objects.get_or_create(field1=1)
row.other_field = 2
row.save()

I do have a unique constraint on field1. If there is a row where field1=1, everything works fine, Django does a "get".

If there is not a row where field1=1, it looks like Django is creating that row which is ok. But why won't it let me save it?

Update:

If it helps, here is MyModel:

class MyModel(models.Model):
    id = models.BigIntegerField(primary_key=True)
    field1 = models.BigIntegerField(unique=True)
    other_field = models.CharField(max_length=765)
    class Meta:
        db_table = u'project_crosses_suppl_FO'

field1 is a foreign key to another table. But I didn't make a model in Django for that table so I don't tell Django it's a foreign key.

Upvotes: 6

Views: 6475

Answers (3)

Rohan Kapoor
Rohan Kapoor

Reputation: 21

Get or Create returns a tuple of results even if your field you use is set as primary key or unique.

So in your case: row is a tuple with one object, hence this should work for you:

(row, is_new) = MyModel.objects.get_or_create(field1=1)
row[0].other_field = 2
row[0].save()

Upvotes: 2

Daniel Roseman
Daniel Roseman

Reputation: 600041

Assuming that's a reasonably faithful representation of your real code, not surprisingly it's not Django that's busted, it's your model.

You've overridden the automatic primary key field with your own id field, but neglected to make it an autoincrement. So the database is not using a new value for the PK, hence the integrity error.

Unless you have a really good reason, you should let Django deal with the PK field itself.

Upvotes: 7

Greg
Greg

Reputation: 47164

get_or_create sounds busted to me. I'm just doing this work around:

rows = MyModel.objects.filter(field1=1)
row = rows[0] if rows else MyModel(field1=1)
row.other_field = 2
row.save()

Upvotes: 3

Related Questions