Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

604
Vistas
'HttpResponseForbidden' object has no attribute

I'm trying to create an api for our users. I've decided to use Django-rest-framework.

Users need only GET requests. Each GET request has to have 'token' attribute to determine which data should we return.

So I've created a function which tries to get user object from request object.

def get_user(request):
    token = request.GET.get('token')
    if not token:
        return HttpResponseForbidden()
    user = get_object_or_404(User,auth_token=token)
    return user

I want to use this function in my view:

@api_view(['GET'])
def products(request):
    user = get_user(request)
    products = user.products.all()
    serializer = ProductSerializer(products, many=True)
    return JsonResponse(serializer.data, safe=False)

The problem is that when I doesn't provide token attribute, it raises:

AttributeError at /api/products/

Exception Value: 'HttpResponseForbidden' object has no attribute 'products'

Instead of proper response.

I can do:

@api_view(['GET'])
def products(request):
    user_or_response = get_user(request)
    if user_or_response.__class__ != User:
        return _or_response
    products = _or_response.products.all()
    serializer = ProductSerializer(products, many=True)
    return JsonResponse(serializer.data, safe=False)

As you can see, it doesn't automatically return forbidden response, instead, it returns it as user. I can return it in products view but maybe there is a better way to do this with Django-rest-framework.

What should I do? Do you have a better approach or any advice?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Yeah, the HttpResponseForbidden is returned into your function, not from the view.

In this situation, you can try the following approach

def get_user(request):
    token = request.GET.get('token')
    if not token:
        return False
    user = get_object_or_404(User,auth_token=token)
    return user

@api_view(['GET'])
def products(request):

    user = get_user(request)
    if not user:
        return HttpResponseForbidden()
    products = user.products.all()
    serializer = ProductSerializer(products, many=True)
    return JsonResponse(serializer.data, safe=False)

You can also potentially raise the exception instead of returning it in get_user and then handle it with a try/except inside the view.

Either way, it's just a little cleaner than comparing .__class__ to User.

over 4 years ago · Santiago Trujillo Denunciar

0

So, right now it looks like you're muddling the difference between your model and your view. The model is the thing that looks up data. It generally should not be returning response code or handling validation with errors.

Python's behavior is correct, however. You are returning an object from get_user and then you are telling it to expect a products property on the returned object.

If I were you, I would do this:

def get_user(request):
    token = request.GET.get('token')
    if not token:
        return
    user = get_object_or_404(User,auth_token=token)
    return user


@api_view(['GET'])
def products(request):
    user = get_user(request)
    if not user:
        return HttpForbiddenResponse()
    products = user.products.all()
    serializer = ProductSerializer(products, many=True)
    return JsonResponse(serializer.data, safe=False)

I would NOT check the class. Not only does this not fair very well in Pythonic philosophy, but it also means that you can't do something like create an AdminUser(User) class. If you really want to return an arbitrary value from get_user, then I would do:

@api_view(['GET'])
def products(request):
    user = get_user(request)
    if not hasattr(user, 'products'):
        return HttpForbiddenResponse()

That will check for a defined property, which matches OOP and a slightly more Pythonic approach.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda