URLs and side effects (Django)
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Ominous Technology Looping
--
Chapters
00:00 Urls And Side Effects (Django)
01:43 Answer 1 Score 1
02:01 Answer 2 Score 0
02:38 Answer 3 Score 1
04:06 Accepted Answer Score 2
04:51 Thank you
--
Full question
https://stackoverflow.com/questions/3126...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #django #url #post #djangoviews
#avk47
ACCEPTED ANSWER
Score 2
A modified option #1 is the best approach. Consider this: suppose we weren't talking about a web app, but instead were just designing an inbox class. Which do you like better, a number of methods (delete_message(), mark_as_spam(), etc), or one big method (do_stuff(action))? Of course you would use the separate methods.
A separate URL for each action, each with a separate view, is far preferable. If you don't like the redirect at the end, then don't use it. Instead, have a render_inbox(request) method that returns an HttpResponse, and call the method at the end of each of your views. Of course, redirecting after a POST is a good way to prevent double-actions, and always leaves the user with a consistent URL.
Even better might be to use Ajax to hide the actions, but that is more involved.
ANSWER 2
Score 1
I don't think there's anything wrong with either option, but #2 is potentially better from a performance standpoint. After the action is posted you can render the inbox without a redirect, so it cuts down on the HTTP traffic.
ANSWER 3
Score 1
If you're writing a web 2.0 messaging app, you would be using AJAX calls and wouldn't be loading a new page at all. The process would proceed like so:
User clicks [delete] for a message. This button has a javascript action bound to it. This action does the following:
i. Change the UI to indicate that something is happening (grey the message or put up an hourglass).
ii. Send a request to /messages/inbox/1234/delete. (where 1234 is some identifier that indicates which message)
iii. When the response from the server comes back, it should indicate success or failure. Reflect this status in the current UI. For example, on success, refresh the inbox view (or just remove the deleted item).
On the server side, now you can create a URL handler for each desired action (i.e. /delete, /flag, etc.).
If want to use an even more RESTful approach, you would use the HTTP action itself to indicate the action to perform. So instead of including delete in your URL, it would be in the action. So instead of GET or POST, use DELETE /messages/inbox/1234. To set a flag for having been read, use SET /messages/inbox/1234?read=true.
I don't know how straightforward it is in Django to implement this latter recommendation, but in general, it's a good idea utilize the protocol (in this case HTTP), rather than work around it by encoding your actions into a URL or parameter.
ANSWER 4
Score 0
I agree that #2 is a better approach.
But take care with overloading the submit <input /> with different methods -- if a user is using it with keyboard input and hits enter, it won't necessarily submit the <input /> you're expecting. Either disable auto-submit-on-enter, or code things up so that if there is more than one thing that submit can do, there's another field that sets what the action should be (eg a 'delete' checkbox, which is tested during a request.POST)
If you went with #1 I'd say that a GET to a POST-only view should be met with a 405 (method not supported) - or, failing that, a 404.