Django: фильтровать набор запросов по свойству элемента - PullRequest
1 голос
/ 14 марта 2020

У меня есть две модели, Chat и DeletedChat. Теперь я хочу получить все чаты user, удалив те, чьи from_date -поля в DeletedChat больше, чем last_updated чата самого чата. Как мне это сделать?

class Chat(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    last_updated = models.DateTimeField(auto_now=True)

class DeletedChat(models.Model):
    chat = models.ForeignKey(Chat, on_delete=models.CASCADE)
    from_date = models.DateTimeField(default=timezone.now)

И в моем views.py я попробовал:

chat_ids = request.user.deletedchat_set.exclude(from_date__lt='chat__last_updated').values_list('chat', flat=True)

, что дает мне следующую ошибку: ['“chat__message__set__last” value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.']

Спасибо за вашу помощь!

1 Ответ

1 голос
/ 14 марта 2020

Вы можете работать с объектом F для обращения к полю:

from django.db.models import F, Q

Chat.objects.filter(Q(deletedchat=None) | Q(deletedchat__form_date__lt=F('last_updated')))

Это вернет Chat объектов, для которых есть нет связанных DeletedChat объектов или когда объект DeletedChat имеет form_date, который меньше поля last_updated объекта Chat.

Мы также можем использовать .exclude():

from django.db.models import F

Chat.objects.exclude(<b>deletedchat__form_date__gte=F('last_updated')</b>)

Однако оба не эквивалентны, если есть несколько связанных DeleteChat объектов. В этом случае вариант .filter(..) все еще может содержать Chat, если существует хотя бы один связанный объект DeleteChat, для которого from_date меньше поля last_updated. Для .exclude() он будет исключен из момента, когда один из from_date s больше, чем поле last_updated.

В случае, если объект Chat имеет не более одного объекта DeletedChat вы можете вместо этого указать OneToOneField [Django -doc] .

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