0

Can't figure out a good way to filter by many to many relation.

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')

Now suppose I have a list of numbers, for example:

hours = [2,4,6]

I want to find a Scheduler which has this exact set of WeekHour objects with these hour values.

So it returns scheduler if and only if there is some which has this weekhours set [WeekHour(hour=2),WeekHour(hour=4),WeekHour(hour=6)]. So the number of related WeekHours must be the same as a size of the list. In this case 3.

Is this possible using Django orm and not using cycles?

EDIT:

What about this?

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

This returns:

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

Milano
  • 18,048
  • 37
  • 153
  • 353

1 Answers1

0

__exact is expecting the same type as the field type.

You should consider using __in and then chaining Q expressions on operator.and_ to filter the exact object that has a relation to the ids of all the related objects:

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]))
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • I'm afraid this doesn't work correctly. For testing purposes I have two scheduler objects. First has weekhours = [WeekHour(hour=2),WeekHour(hour=4),WeekHour(hour=6)] and the second has all weekhours possible ( WeekHour(hour= – Milano Dec 11 '16 at 18:30
  • And schedulers are distinct (there are no two schedulers with the same WeekHour set). – Milano Dec 11 '16 at 18:31
  • Unfortunately this doesn't return anything. If I print weekhours_set, it returns . Should it be queryset? – Milano Dec 11 '16 at 18:53
  • You probably want to `filter` in a `for`: http://stackoverflow.com/questions/16324362/django-queryset-get-exact-manytomany-lookup – Moses Koledoye Dec 11 '16 at 18:59