У меня есть модель:
class Zone(models.Model):
name = models.CharField(max_length=128)
users = models.ManyToManyField(User, related_name='zones', null=True, blank=True)
И мне нужно построить фильтр по строкам:
u = User.objects.filter(...zones contains a particular zone...)
Это должен быть фильтр для пользователя, и это должен быть единственный параметр фильтра. Причина этого в том, что я создаю строку запроса URL для фильтрации списка изменений пользователей администратора:http://myserver/admin/auth/user/?zones=3
Кажется, это должно быть просто, но мой мозг не работает!
django
django-models
Энди Бейкер
источник
источник
User.objects.filter(zones__id=<id>)
илиUser.objects.filter(zones__in=<id(s)>)
подходит для этого?User.objects.filter(zones__in=<id(s)>)
наверное, должно бытьUser.objects.filter(zones__id__in=<id(s)>)
Ответы:
Просто повторю то, что сказал Томаш.
В тестах
FOO__in=...
« многие ко многим» и « многие к одному» можно найти множество примеров фильтров стиля . Вот синтаксис вашей конкретной проблемы:Синтаксис двойного подчеркивания (__) используется повсеместно при работе с наборами запросов .
источник
...__in
примеры после# filtering on a few zones, by id
. Они показывают фильтрацию для нескольких идентификаторов / объектов (в данном случае). Просто передайте нужные вам идентификаторы / объекты zone1, zone3 и zone10. Или при необходимости добавьте четвертую.Обратите внимание: если пользователь может находиться в нескольких зонах, используемых в запросе, возможно, вы захотите добавить
.distinct()
. В противном случае вы получите одного пользователя несколько раз:источник
другой способ сделать это - пройти через промежуточную таблицу. Я бы выразил это в Django ORM так:
было бы хорошо, если бы он не нуждался в
.values('user')
указанном, но Django (версия 3.0.7), похоже, нуждается в нем.приведенный выше код в конечном итоге сгенерирует SQL, который выглядит примерно так:
что приятно, потому что у него нет промежуточных соединений, которые могли бы привести к возврату повторяющихся пользователей
источник