Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django get_or_create method doesn't return exact object

Here is my models.py:

class Foo(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=30)

In django manage.py shell:

>>> a,b = Foo.objects.get_or_create(name='hi')
>>> b
True
>>> vars(a)
{'_state': <django.db.models.base.ModelState object at 0x02761390>, 'id': None,
'name': 'hi'}

The problem here is the customized id attribute has no value. And if I continue to do the following:

>>> c = foo.objects.get(name='hi')
>>> c.id
1
>>> a is c
False

So that newly created object (denoted by c) already exists now, but b is not an exact reference to it like c is.

Is this a bug? My django version is 1.6.5.

like image 829
wlnirvana Avatar asked Aug 22 '26 18:08

wlnirvana


1 Answers

By default, if you have not specified the id field for you model, Django will create AutoField:

id = models.AutoField(primary_key=True)

In your case you've created just IntegerField. I suppose this is the point. In the database, it will still be incremented, but django won't assign the id value from database to the object, returned by get_or_create

By the way, in your question:

>>> b is c
False

b - is a bool value. I think you were trying to do

>>> a is c

But also this is not a good idea. If you want to compare django model objects, use ==, not is:

>>> a == c

You will get False anyway, as a has its id set to None.

like image 66
stalk Avatar answered Aug 25 '26 09:08

stalk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!