Правильний спосіб використання get_or_create?


203

Я намагаюся використовувати get_or_create для деяких полів моїх форм, але я отримую помилку 500, коли намагаюся це зробити.

Один з рядків виглядає так:

customer.source = Source.objects.get_or_create(name="Website")

Помилка, яку я отримую для наведеного вище коду, є:

Cannot assign "(<Source: Website>, False)": "Customer.source" 
   must be a "Source" instance.

Відповіді:


353

З документації 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

Пояснення: поля, які оцінюються на схожість, повинні бути зазначені зовні defaults. Решта полів повинні бути включені в defaults. У разі виникнення події CREATE всі поля враховуються.

Схоже, вам потрібно повертатися в кортеж, а не в одну змінну:

customer.source,created = Source.objects.get_or_create(name="Website")

3
Створений FYI є булевим. Щоправда, якщо створено, Неправдиво, якщо його знайдено
Джош

3
Додаткове save()зайве?
зипро

@zypro Це як create(), створіть об’єкт і збережіть це все за один крок і йому не потрібноsave()
Амін Мир,

32

get_or_create повертає кортеж.

customer.source, created = Source.objects.get_or_create(name="Website")

16
Або, якщо вас не хвилює булевий прапор:customer.source = Source.objects.get_or_create(name="Website")[0]
mipadi

7
@mipadi Я вважаю за краще customer.source, _ = Source.objects.get_or_create(name="Website"), оскільки це робить факт повернення кортежу більш очевидним, що допомагає уникнути майбутніх помилок.
Соломон Учко

15

get_or_create() повертає кортеж:

customer.source, created  = Source.objects.get_or_create(name="Website")
  • created має булеве значення, створюється чи ні.

  • customer.source має об’єкт get_or_create()методу.


12

Після відповіді @Tobu та коментаря @mipadi, більш пітонічним способом, якщо я не зацікавлений у створеному прапорі, я би використав:

customer.source, _ = Source.objects.get_or_create(name="Website")

4

Проблема, з якою ви стикаєтесь, є документально підтвердженою особливістю get_or_create.

При використанні аргументів ключових слів, окрім "за замовчуванням", значення повернення get_or_create- це екземпляр. Ось чому він показує вам паролі у зворотному значенні.

ви можете використовувати customer.source = Source.objects.get_or_create(name="Website")[0]для отримання правильного значення.

Ось посилання на документацію: http://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create-kwargs

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.