Django post_delete: подсчитать все объекты, которые имеют один соответствующий атрибут с удаленным объектом - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть пользовательская функция, которая вызывается при удалении объекта модели заказов, для этого я использую post_delete.

Экземпляр модели «Заказы» всегда имеет ForeignKey «пользователь». При удалении объекта модели «Заказы» я хочу проверить, есть ли другие экземпляры модели «Заказы» с тем же «пользователем».

def delete_reverse(sender, **kwargs):
try:
    if Orders.objects.filter(user__equal=kwargs['instance'].user).count() == 1:
        kwargs['instance'].user.delete()
    else:
        ...         
except:
    pass
post_delete.connect(delete_reverse, sender=Orders)

К сожалению, условие if не работает, то есть оно неверно, даже если количество соответствующих записей должно быть 1. Вы видите какие-либо проблемы с моей функцией count ()?

1 Ответ

0 голосов
/ 13 сентября 2018

Я думаю, что есть некоторые проблемы с этим кодом:

  1. Похоже, вы используете поиск полей __equal, но этот поиск не существует в списке стандартных поисков полей [Django-doc] , ближайший __exact, но, вероятно, здесь нет необходимости;
  2. вы используете " общее исключение " (!), Это серьезный анти-шаблон : если что-то не работает, вы никогда не будете проинформированы об этом. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10 * *.
  3. Пост-удаление означает, что удаление уже произошло, следовательно, в этот момент экземпляр больше не находится в базе данных, как указано в документации :

    Обратите внимание, что объект больше не будет в базе данных, поэтому будьте очень осторожны с тем, что вы делаете с этим экземпляром.

Последний пункт, таким образом, означает, что вы, вероятно, захотите проверить, равно ли число нулю (следовательно, Order с этим user_id больше не существует):

@receiver(post_save, sender=Orders)
def delete_reverse(sender, instance, **kwargs):
    if not Order.objects.filter(user_id=instance.user_id).exists():
        instance.user.delete()

Обратите внимание, что даже при этом все еще существуют сценарии, в которых база данных может содержать User с без Order с: например, когда мы изменяем user_id на Order, тогда возможно что предыдущий пользователь больше не имеет, но эта функция не сработает. Так что, возможно, стоит периодически проверять базу данных на такие случаи.

Более того, я не знаю, хорошая ли идея удалить User. Если это модель аутентификации в Django, это может привести к тому, что пользователь с правами администратора будет удален, если, например, случайно на его имя был наложен приказ и этот заказ будет удален позже. Кроме того, удаление пользователя может привести к большому каскаду удалений (всех видов «сущностей», в которых участвует этот пользователь).

Примечание : модель Django обычно имеет единственное имя , поэтому я, как и в ответе, рекомендую переименовать модель Orders в Order.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...