Reputation: 2412
I have a company
model, each instance of which has a foreign_key named admin
to a user.
I am writing a view to allow company admins to administer their companies:
urls.py
:
path('admin/crn=<company_spec_url>', CompanyAdminView.as_view(), name="CompanyAdminView"),`
views.py
:
class CompanyAdminView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
template_name = 'company_admin.html'
def test_func(self):
company = Company.objects.filter(crn=context['company_spec_url'])[0]
return company.admin == self.user
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['company'] = Company.objects.filter(crn=context['company_spec_url'])[0]
context['announcements'] = CompanyAnnouncement.objects.filter(company__crn=context['company_spec_url'])
return context
The get_context_data
bit is working fine, the issue is in the test_func
. Clearly only the company's admin should be allowed to administer a company, so I am trying to get the into the test_func
, in order to test against it.
The code in test_func
does not currently work, because it does not have access to context
. Is it best practice to: Call super().get_context_data
once, and make context
a global variable so that it can be accessed from test_func
- Call super().get_context_data
twice, once in get_context_data
and once in test_func
, or something else entirely?
I've tried looking at the GET dict in the request, but it's empty. I could just parse the url within test_func
to get the parameter myself, but it doesn't seem like the 'correct' way to do it.
Upvotes: 3
Views: 5241
Reputation: 477606
The positional and named parameters are stored in self.args
and self.kwargs
respectively, so you can access it with:
class CompanyAdminView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
# ...
def test_func(self):
company = Company.objects.filter(crn=self.kwargs['company_spec_url'])[0]
return company.admin == self.user
Note that the above can be tricky: here if multiple companies have the same crn
, then you will let a (possibly random) order decide what company you pick, and whether that admin
is the self.user
. Furthermore it will here result in two queries.
class CompanyAdminView(LoginRequiredMixin, UserPassesTestMixin, TemplateView):
# ...
def test_func(self):
return Company.objects.filter(
crn=self.kwargs['company_spec_url']
admin=self.user
).exists()
With the above we check if there is a Company
that has as crn
the parameter in the URL, and self.user
as admin
.
Upvotes: 5