2016-12-11 6 views
0

Невозможно найти хороший способ фильтрации по многим отношениям.Фильтровать объекты по многим отношениям

class Scheduler(models.Model): 
    weekhours = models.ManyToManyField('WeekHour', related_name='schedulers') 

    def get_active_products_by_weekhour(self,weekhour): 
     return Product.objects.filter(scheduler__in=WeekHour.objects.get(hour=weekhour).schedulers.all()) 


class WeekHour(models.Model): 
    hour = models.PositiveSmallIntegerField(verbose_name='Hour in week (0 - 7*24') 

Теперь предположим, что у меня есть список номеров, например:

hours = [2,4,6] 

Я хочу найти планировщика, который имеет этот точный набор WeekHour объектов с этими hour значениями.

Таким образом, он возвращает планировщик, если и только если есть некоторые, у которых установлен этот набор часов [WeekHour(hour=2),WeekHour(hour=4),WeekHour(hour=6)]. Поэтому количество связанных недельных часов должно быть таким же, как размер списка. В этом случае 3.

Возможно ли это, используя Django orm и не используя циклы?

EDIT:

Что относительно этого?

weekhours_set = [Weekhour.objects.get(hour=x) for x in hours] 
scheduler = Scheduler.objects.filter(weekhours__exact=weekhours_set) 

Это возвращает:

TypeError: int() argument must be a string or a number, not 'list'

ответ

0

__exact ожидает того же типа, что и тип поля.

Вы должны рассмотреть возможность использования __in, а затем цепочки Q выражения на operator.and_ к фильтраточный объект, который имеет отношение к идентификаторам всех связанных с ними объектов:

import operator 
from django.db.models import Q 

weekhours_set = Weekhour.objects.filter(hour__in=hours).values_list('id', flat=True) 
schedulers = Scheduler.objects.filter(reduce(operator.and_, [Q(weekhours__id=id) for id in weekhours_set])) 
+0

Я боюсь, что это Безразлично работайте правильно. Для целей тестирования у меня есть два объекта планировщика. Вначале есть недельные часы = [WeekHour (час = 2), WeekHour (час = 4), WeekHour (час = 6)], а второй - все возможные недели (WeekHour (час = <от 1 до 7 * 24)), и он возвращается и то и другое. Но часы [2,4,6], поэтому я хочу вернуть только первый. Набор WeekHour должен быть точным. –

+0

И планировщики различны (нет двух планировщиков с тем же набором WeekHour). –

+0

@MilanoSlesarik См. Мой обновленный ответ –

Смежные вопросы