Django: проверьте, существует ли объект перед добавлением
Это довольно простой вопрос Django, но я не могу найти ответ в документах Django, несмотря на много охоты!
Как проверить, существует ли объект, и добавлять его только в том случае, если он еще не существует?
Здесь код - я не хочу добавлять follow_role дважды в базу данных, если он уже существует. Как я могу проверить сначала? Использовать get() возможно - но тогда Django будет жаловаться, если get() ничего не возвращает?
current_user = request.user
follow_role = UserToUserRole(from_user=current_user, to_user=user, role='follow')
follow_role.save()
Спасибо!
Ответы
Ответ 1
Здесь есть вспомогательная функция для этой идиомы, называемая "get_or_create" в диспетчере моделей:
role, created = UserToUserRole.objects.get_or_create(
from_user=current_user, to_user=user, role='follow')
Он возвращает кортеж (model, bool), где "модель" - это объект, который вас интересует, и "bool" сообщает вам, нужно ли его создавать или нет.
Ответ 2
Если вы используете последнюю версию Django, вы можете использовать опцию unique_together для модели UserToUserRole, а затем использовать get_or_create() Джо Холлоуэй показал. Это гарантирует, что вы не сможете получить дубликат.
Ответ 3
Если вы хотите, чтобы проверка выполнялась каждый раз перед сохранением, вы можете использовать предварительно сохраненный сигнал для проверки, http://docs.djangoproject.com/en/dev/ref/signals/#django.db.models.signals.pre_save
В качестве альтернативы в модели вы можете указать unique = True для свойства, которое определяет, является ли элемент одним и тем же элементом, это приведет к выбросу исключения (django.db.IntegrityError), если вы попытаетесь сохранить то же самое снова.
Если у вас более одного поля вместе, что делает что-то уникальное, вам нужно использовать unique_together в внутреннем классе Meta http://docs.djangoproject.com/en/dev/ref/models/options/#unique-together
Ответ 4
Вы можете использовать get(), но вам придется обернуть его с помощью try-except, например:
try:
obj = UserToUserRole.objects.get(from_user=current_user, to_user=user, role='follow')
except UserToUserRole.DoesNotExist:
# here write a code to create a new object