I've been working on a project for a while, and I have a resource called Item.
The item detail view can only be viewed, if the item is from the same company as the user. If not, it should be a 404. This is the code that I have:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# To only show items in your company
if (context['item'].company != getCompany(self.request.user)):
return HttpResponseNotFound
return context
getCompany
is a function I wrote to check the users company. The company is in a custom Profile
model. This function works, I already used it multiple times for other things
Now i expected to have a 404 when going to a item from another company, but instead this error appears:
Internal Server Error: /fr/items/5/
Traceback (most recent call last):
File "/Users/username/Documents/Work/Inventory/inventory-env/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/Users/username/Documents/Work/Inventory/inventory-env/lib/python3.9/site-packages/django/core/handlers/base.py", line 220, in _get_response
response = response.render()
File "/Users/username/Documents/Work/Inventory/inventory-env/lib/python3.9/site-packages/django/template/response.py", line 114, in render
self.content = self.rendered_content
File "/Users/username/Documents/Work/Inventory/inventory-env/lib/python3.9/site-packages/django/template/response.py", line 92, in rendered_content
return template.render(context, self._request)
File "/Users/username/Documents/Work/Inventory/inventory-env/lib/python3.9/site-packages/django/template/backends/django.py", line 58, in render
context = make_context(
File "/Users/username/Documents/Work/Inventory/inventory-env/lib/python3.9/site-packages/django/template/context.py", line 278, in make_context
raise TypeError(
TypeError: context must be a dict rather than type.
Edited:
What did I miss?
CodePudding user response:
as Django doc
def get_context_data(self, **kwargs):
is used to
Returns a dictionary representing the template context. The keyword arguments provided will make up the returned context
and you are trying to return HttpResponseNotFound, that will not work, you should return dict type
CodePudding user response:
The get_context_data(...)
method supposed to be return a dict
object. In your case, you are returning a HttpResponseNotFound
which is not correct.
The easy method to raise the 404
error is to use the Http404
class to raise the exception
from django.http import Http404
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# To only show items in your company
if (context['item'].company != getCompany(self.request.user)):
raise Http404
return context
CodePudding user response:
Rather raise a PermissionDenied
error, then return a Response
incorrectly as the context, it gives better meaning, then Django will return the usual 403 page.
from django.core.exceptions import PermissionDenied
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# To only show items in your company
if (context['item'].company != getCompany(self.request.user)):
raise PermissionDenied("You are not authorized to view the requested company")
return context