Tiago Peres
Tiago Peres

Reputation: 15476

Show only users that don't yet exist in the through table

Inside of the __init__ method of a form ProjectUserCreateForm(forms.ModelForm) to add Users to a Project (Project model has a users = models.ManyToManyField(...)) I have

self.fields['users'].queryset = User.objects.filter(company=self.request.user.company)

This way I'm able to show only the users to be added to the Project that belong to the company of the user requesting the page.

This form can be found in

path('<int:pk>/users/create/', views.ProjectUserCreateView.as_view(), name='project-user-create'),

where the <int:pk> is the PK of the Project, and ProjectUserCreateView is a CBV CreateView.

How can I show only the users that belong to the company of the logged in user (this part already works) AND that don't yet exist in the through table (the table based on the ManyToManyField)?

Upvotes: 1

Views: 78

Answers (1)

nigel239
nigel239

Reputation: 1765

You can get all users that do not yet belong to the request.user's company with:

users_in_company = request.user.company.user_set.all().values(pk).distinct()
users_not_in_company = User.objects.all().exclude(pk__in=list(users_in_company))

Bonus: If you want to get all users which don't belong to any company:

users_not_in_any_company = users_not_in_company.filter(company__isnull=True) # Equal to User.objects.filter(company__isnull=True), but it doesn't really matter.

Note:

request.user.company.user_set.all()

If you changed the related name of the user to the company, change user_set too ofcourse. I could give you the full example code, but alas, no models.

Edit:

To get all users in a company if the request.user has one:

users = request.user.company.user_set.all()

To filter those users which belong to a specific project:

users.filter(project=my_project)

To get users that don't belong to the project:

users = User.objects.all().exclude(project__pk=self.kwargs['pk'])

To get users that belong to the request.user's company, but not to a project:

request.user.company.user_set.all().exclude(project__pk=self.kwargs['pk'])

Final

User.objects.filter(company=self.request.user.company).exclude(project_users=project_pk)

Upvotes: 1

Related Questions