Django: как фильтровать пользователей, принадлежащих к определенной группе
Я ищу, чтобы сузить набор запросов для поля формы, в котором пользовательский ключ находится в таблице User, до группы, к которой принадлежит пользователь.
Группы ранее были связаны мной. Модель может иметь что-то вроде следующего:
myuser = models.ForeignKey(User)
И мой ModelForm - очень голые кости:
class MyForm(ModelForm):
class Meta:
model = MyModel
Поэтому, когда я создаю экземпляр формы, я делаю что-то вроде этого в моих views.py:
form = MyForm()
Теперь мой вопрос: как я могу взять поле myuser и фильтровать его, чтобы отображались только пользователи группы "foo".. что-то вроде:
form.fields["myuser"].queryset = ???
Запрос в SQL выглядит следующим образом:
mysql> SELECT * from auth_user INNER JOIN auth_user_groups ON auth_user.id = auth_user_groups.user_id INNER JOIN auth_group ON auth_group.id = auth_user_groups.group_id WHERE auth_group.name = 'client';
Я бы хотел избежать использования raw SQL. Можно ли это сделать?
Ответы
Ответ 1
Вы хотите использовать соглашение Django для соединения между отношениями, чтобы присоединиться к таблице групп в вашем наборе запросов.
Во-первых, я рекомендую дать вам отношения related_name
. Это делает код более читаемым, чем по умолчанию Django.
class Group(models.Model):
myuser = models.ForeignKey(User, related_name='groups')
Если вы хотите только одну группу, вы можете присоединиться к этому соединению и сравнить поле имени с помощью любого из этих методов:
form.fields['myuser'].queryset = User.objects.filter(
groups__name='foo')
form.fields['myuser'].queryset = User.objects.filter(
groups__name__in=['foo'])
Если вы хотите квалифицировать несколько групп, используйте предложение in
:
form.fields['myuser'].queryset = User.objects.filter(
groups__name__in=['foo', 'bar'])
Если вы хотите быстро увидеть сгенерированный SQL, вы можете сделать это:
qs = User.objects.filter(groups__name='foo')
print qs.query
Ответ 2
Это действительно старый вопрос, но для тех, кто пытается найти ответ на этот вопрос (как и я), пожалуйста, знайте, что принятый ответ больше не на 100% правильный. Пользователь может принадлежать нескольким группам, поэтому, чтобы правильно проверить, находится ли пользователь в какой-либо группе, вы должны:
qs = User.objects.filter(groups__name__in=['foo'])
Конечно, если вы хотите проверить несколько групп, вы можете добавить их в список:
qs = User.objects.filter(groups__name__in=['foo', 'bar'])