Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

596
Visualizações
'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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda