Не удается написать правильный набор запросов фильтрации

#django #django-queryset

#django #django-queryset

Вопрос:

Существует такая модель типа контента:

 class CTModel(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    sport = models.ForeignKey(SportTypes)
  

Наборы запросов:

 user_type = ContentType.objects.get_for_model(UserProfile)
current_sport = Sports.objects.get(name='Football')
rest_sports = Sports.objects.filter(name__in=RANDOM LIST OF GAMES).exclude(name='Football')

# Here I want to get all users who play 'Football'
users_play_football = CTModel.objects.filter(content_type=user_type, sport=current_sport)

# Here I want to get all users, who play Football,
# but at the same time, does not play any other games from 'rest_sports'
users = users_play_football.exclude(sport=rest_sports)
  

Я хочу получить users некоторый контент (пользователей) на всякий случай, если пользователи играют только в футбол, и если пользователи играют в какие-либо другие игры, users не следует включать таких пользователей. Теперь, если пользователи играют как в «Футбол», так и в что-то из rest_sports , эти пользователи не исключаются users .

В чем моя ошибка?

Ответ №1:

 users = users_play_football.exclude(sport__in=rest_sports)
  

Ответ №2:

Похоже, проблема была в логике моих наборов запросов. В приведенном выше подходе queryset исключается только rest_sports из пользователя и не удаляет самого пользователя users .

Здесь есть решение:

 users_play_football = CTModel.objects.filter(content_type=user_type, sport=current_sport).values_list('object_id', flat=True)
users_w_rest_games = CTModel.objects.filter(content_type=user_type, sport=rest_sports).values_list('object_id', flat=True)

if users_w_rest_games:
    users = users_play_football.exclude(object_id__in=users_w_rest_games)
else:
    users = users_play_football
  

В моем случае кажется, что .exclude это не работает по мере необходимости с необработанными наборами запросов, потому exclude что на самом деле ничего не исключает. Вот почему я использую values_list('object_id', flat=True) для object_id явного предоставления пользователям.