Django: Как отфильтровать пользователей, принадлежащих к определенной группе - PullRequest
29 голосов
/ 28 ноября 2009

Я хочу сузить набор запросов для поля формы с внешним ключом к таблице пользователя до группы, к которой принадлежит пользователь.

Группы были ранее связаны со мной. Модель может иметь что-то вроде следующего:

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

Я бы хотел избежать использования сырого SQL. Возможно ли это сделать?

Ответы [ 2 ]

45 голосов
/ 28 ноября 2009

Вы захотите использовать Соглашение 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 
16 голосов
/ 09 декабря 2014

Это действительно старый вопрос, но для тех, кто ищет ответ на этот вопрос (как и я), пожалуйста, знайте, что принятый ответ уже не на 100% правильный. Пользователь может принадлежать к нескольким группам, поэтому для правильной проверки, входит ли пользователь в какую-либо группу, необходимо сделать:

qs = User.objects.filter(groups__name__in=['foo'])

Конечно, если вы хотите проверить несколько групп, вы можете добавить их в список:

qs = User.objects.filter(groups__name__in=['foo', 'bar'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...