Обновление в Django для UniqueConstraint

Я пытаюсь работать с UniqueConstraint, но столкнулся с некоторыми проблемами, пытаясь обновить его так, как мне нужно.

У меня есть следующая модель

class QueryModel(models.Model):

    id = models.AutoField(_("query id"), primary_key=True)
    user = models.ForeignKey(UserModel, on_delete=models.CASCADE)
    name = models.CharField(_("query name"), max_length=150)
    status = models.CharField(
        _("query status"),
        choices=QueryStatus.choices,
        default=QueryStatus.ACTIVE,
    )
    is_favorite = models.BooleanField(_("favorite"), default=False)
    date_created = models.DateTimeField(_("date created"), auto_now_add=True)

    class Meta(object):
        app_label = "app"
        db_table = "query"
        constraints = [
            models.UniqueConstraint(
                fields=("user",),
                condition=Q(is_favorite=True),
                name="unique_favorite_per_user",
            )
        ]

В моей системе пользователи могут создавать запросы и устанавливать их в качестве избранных, но у каждого пользователя может быть только 1 избранный запрос, поэтому я создал UniqueConstraint, чтобы обеспечить соблюдение этого бизнес-правила.

Тогда у меня будет конечная точка для установки запроса как избранного, но есть ли способ обновить это поле без необходимости проверять все поля is_favorite у каждого пользователя и вручную устанавливать их в False?

Я нашел это сообщение StackOverflow 2-летней давности, в котором предлагается решение, но это решение не работает для меня, я был бы очень признателен за помощь

Если вы хотите установить QueryModel с my_pk в качестве первичного ключа как избранный, вы обновляете с помощью:

from django.db.models import BooleanField, ExpressionWrapper, Q

QueryModel.objects.filter(user=my_user).update(
    is_favorite=ExpressionWrapper(Q(pk=my_pk), BooleanField())
)

Это автоматически отключит избранное, если оно уже есть, и установит его на то, у которого my_pk первичный ключ.

Альтернативно, мы можем работать с двумя обновлениями, одно из которых устанавливает все строки в False, а другое - в True:

QueryModel.objects.filter(user=my_user).update(is_favorite=False)
QueryModel.objects.filter(user=my_user, pk=my_pk).update(is_favorite=True)
Вернуться на верх