Correct way to use get_or_create?
I'm trying to use get_or_create for some fields in my forms, but I'm getting a 500 error when I try to do so.
One of the lines looks like this:
customer.source = Source.objects.get_or_create(name="Website")
The error I get for the above code is:
Cannot assign "(<Source: Website>, False)": "Customer.source"
must be a "Source" instance.
Solution 1:
From the documentation get_or_create:
# get_or_create() a person with similar first names.
p, created = Person.objects.get_or_create(
first_name='John',
last_name='Lennon',
defaults={'birthday': date(1940, 10, 9)},
)
# get_or_create() didn't have to create an object.
>>> created
False
Explanation:
Fields to be evaluated for similarity, have to be mentioned outside defaults
. Rest of the fields have to be included in defaults
. In case CREATE event occurs, all the fields are taken into consideration.
It looks like you need to be returning into a tuple, instead of a single variable, do like this:
customer.source,created = Source.objects.get_or_create(name="Website")
Solution 2:
get_or_create
returns a tuple.
customer.source, created = Source.objects.get_or_create(name="Website")
Solution 3:
get_or_create()
returns a tuple:
customer.source, created = Source.objects.get_or_create(name="Website")
created
→ has a boolean value, is created or not.customer.source
→ has an object ofget_or_create()
method.
Solution 4:
Following @Tobu answer and @mipadi comment, in a more pythonic way, if not interested in the created flag, I would use:
customer.source, _ = Source.objects.get_or_create(name="Website")
Solution 5:
The issue you are encountering is a documented feature of get_or_create
.
When using keyword arguments other than "defaults" the return value of get_or_create
is an instance. That's why it is showing you the parens in the return value.
you could use customer.source = Source.objects.get_or_create(name="Website")[0]
to get the correct value.
Here is a link for the documentation: http://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create-kwargs