Home > Back-end >  context must be a dict rather than type
context must be a dict rather than type

Time:10-13

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
  • Related