I'm looking to narrow a query set for a form field that has a foreignkey to the User's table down to the group that a user belongs to.
The groups have been previously associated by me. The model might have something like the following:
myuser = models.ForeignKey(User)
And my ModelForm is very bare bones:
class MyForm(ModelForm): class Meta: model = MyModel
So when I instantiate the form I do something like this in my views.py:
form = MyForm()
Now my question is, how can I take the myuser field, and filter it so only users of group 'foo' show up.. something like:
form.fields["myuser"].queryset = ???
The query in SQL looks like this:
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';
I'd like to avoid using raw SQL though. Is it possible to do so?
You can get the groups of a user with request. user. groups. all() , which will return a QuerySet .
To filter a Python Django query with a list of values, we can use the filter method with in . to search Blog entries with pk set to 1,4 or 7 by calling Blog. objects. filter with the pk_in argument set to [1, 4, 7] .
Django-filter is a generic, reusable application to alleviate writing some of the more mundane bits of view code. Specifically, it allows users to filter down a queryset based on a model's fields, displaying the form to let them do this. Adding a FilterSet with filterset_class. Using the filterset_fields shortcut.
Groups. django.contrib.auth.models.Group models are a generic way of categorizing users so you can apply permissions, or some other label, to those users. A user can belong to any number of groups. A user in a group automatically has the permissions granted to that group.
You'll want to use Django's convention for joining across relationships to join to the group table in your query set.
Firstly, I recommend giving your relationship a related_name
. This makes the code more readable than what Django generates by default.
class Group(models.Model): myuser = models.ForeignKey(User, related_name='groups')
If you want only a single group, you can join across that relationship and compare the name field using either of these methods:
form.fields['myuser'].queryset = User.objects.filter( groups__name='foo') form.fields['myuser'].queryset = User.objects.filter( groups__name__in=['foo'])
If you want to qualify multiple groups, use the in
clause:
form.fields['myuser'].queryset = User.objects.filter( groups__name__in=['foo', 'bar'])
If you want to quickly see the generated SQL, you can do this:
qs = User.objects.filter(groups__name='foo') print qs.query
This is a really old question, but for those googling the answer to this (like I did), please know that the accepted answer is no longer 100% correct. A user can belong to multiple groups, so to correctly check if a user is in some group, you should do:
qs = User.objects.filter(groups__name__in=['foo'])
Of course, if you want to check for multiple groups, you can add those to the list:
qs = User.objects.filter(groups__name__in=['foo', 'bar'])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With