0

In my API, sometimes you make HTTP request with id of objects (like update preferred address you put the id of your new default address).

I retrieve it like this:

address = get_object_or_404(
    Address.objects.filter(...), 
    pk=request.data['address_pk']
)

This is completely functional, however it doesn't feel as the best way. I tried to search for the best practice, however I was not able to find proper search term which would satisfy my curiosity.

Is this way of getting a model instance from a request a good practice? Or should it be avoided?

MD. Khairul Basar
  • 4,976
  • 14
  • 41
  • 59
Zygro
  • 6,849
  • 11
  • 28
  • 43
  • It is not clear what exactly you need. – Astik Anand Apr 03 '18 at 08:50
  • 1
    just to know if what I'm doing is a good practice or if I should avoid it. – Zygro Apr 03 '18 at 08:56
  • `get_object_or_404(Address, pk=request.data['address_pk'])` that's it. Yes this is also recommended by Django, and mostly things varies up to the requirement, but for updateview or patch / put API this is enough, also in UpdateView you can completely restrict through queryset – Anup Yadav Apr 03 '18 at 09:05

4 Answers4

0

The common practice is to use the request object correctly. Not the request.data.

pk = request.POST.get('address_pk', 0)
address = get_object_or_404(Address, pk=pk)

You should ONLY use request.POST using the get method.

Andrey Shipilov
  • 1,986
  • 12
  • 14
0

If you are wondering if using request.data is the best option, answer to this question is comparing request.POST and request.DATA

Compare request.POST and request.DATA

Chinczyk
  • 56
  • 3
0
pk=request.data['address_pk']

This will raise a KeyError if address_pk is not present in the request data. Later on, you'll find yourself writing a try...except block to handle it.

A shorter way would be to use the dict.get method.

request.data.get('address_pk') # this will default to None if key is absent

And the KeyError won't raise. This helps reduce 3-4 lines of code.


But this may not always be the best solution, because you might want to maybe send a 400 Bd Request response when a particular key is absent from POST data. In that case, you'll have to write the try...except block for that.

xyres
  • 20,487
  • 3
  • 56
  • 85
0

I can think of one better approach for this can be.

Make URL something like this http://domain.name/address/(?P<id>[0-9]{*})/ using URL Patterns in Django, which will have address ID in URL and can be passed to view as parameter called id and then you can use that to retrieve the Address in same way.

viveksyngh
  • 777
  • 7
  • 15