Подтвердить что ты не робот

Django get_or_create не может установить поле при использовании с iexact

Я хотел бы использовать name__iexact с get_or_create, чтобы избежать дублирования по полям, введенным пользователем, где это возможно.

Модель моего провайдера имеет поле имени, которое я использую в get_or_create.

Поиск работает отлично, но при создании экземпляра в первый раз, как в приведенном ниже примере p1/Timber (имя

Не удается:

>>> p1, c1 = Provider.objects.get_or_create(name__iexact="Timber")
>>> p1, c1
(<Provider: >, True)
>>> p1.name
u''

Работает так, как ожидается здесь:

>>> p2, c2 = Provider.objects.get_or_create(name="Cedar")
>>> p2.name, c2
('Cedar', True)
>>> p3, c3 = Provider.objects.get_or_create(name__iexact="Cedar")
>>> p3, c3
(<Provider: Cedar>, False)
>>> Provider.objects.get_or_create(name__iexact="cedar")
(<Provider: Cedar>, False)

Является ли __iexact несовместимым с частью создания get_or_create, является ли это ожидаемое поведение (и почему), или я запускаю ошибку Django?

4b9b3361

Ответ 1

То, что вы видите, - это правильное поведение.

get_or_create является сокращением для 'get и возвращает совпадение объектов kwargs, если оно не существует, создайте его с помощью defaults'. Ваш поиск ищет объект, где name соответствует нечувствительности к регистру 'cedar'. Этот объект существует, поэтому он возвращается. Ничего больше, не меньше.

Теперь, если совпадение не было, Стефан прав, и вам нужно указать name в параметре defaults. Все поисковые запросы, содержащие разделитель поиска __, удаляются из параметров, переданных в create().

Ответ 2

В соответствии с документацией вы можете попробовать использовать аргументы по умолчанию (не пробуйте этот код):

p1, c1 = Provider.objects.get_or_create(
   defaults={'name':"Timber"}, 
   name__iexact="Timber"
)

Это имеет смысл, поскольку вы можете затем искать и создавать объекты, которые отличаются.