I have a class based view for a Problem
object. I only want the author of the Problem
to be able to view the Problem
cbv. Other logged-in users should be redirected to a forbidden page.
I achieve this by checking the ownership in the get_template_name()
method. But if I want to pass in context to the forbidden template, I also need to check ownership in the get_context_data()
and make the appropriate context.
This works, but it seems like way too much semi-repetitive code, and just very non-Pythonic/Djangonic.
Can any suggest a nicer way to do this? It's an issue for many ClassBasedViews I created. I have both "Problem" objects and "Board" objects that I want to ensure the logged-in user == the author
of the Problem
or Board
object. Almost seems like I could have some kind of Mixin
or something.
Anyway, here is an example of my approach:
class ProblemStudyView(UpdateView):
model = Problem
fields = "__all__"
def get_template_names(self):
problem = self.get_object()
if problem.author != self.request.user:
# User should not see this entry
context = {'original_author': problem.author, 'request_user': self.request.user}
template_name = "board/forbidden.html"
return template_name
else:
# This user is OK
template_name = "board/study.html"
return template_name
def get_context_data(self, **kwargs):
context = super(ProblemStudyView, self).get_context_data(**kwargs)
problem = self.get_object()
# Do the permission check a second time to setup correct context
if problem.author != self.request.user:
context = {'original_author': problem.author, 'request_user': self.request.user}
return context
else:
# User is ok; proceed as normal
return context