URLs and side effects (Django)

I am wondering if it was okay for him (especially in Django) to have a URL intended only for actions with side effects that are intended only for POST access, and this is mostly invisible to the user. Say, in order to make this specific, I have a small messaging system on my site and from their mailbox, the user should be able to do a bunch of things like:

  • Delete message
  • Mark message as read
  • Report abuse as spam

With all of these things causing a page refresh but returning to the same page. I am wondering how to create my own urls and views about this. I see (at least) two options, and I have no idea which is more idiomatic.

Option 1)

You have a separate URL and view for each action. So / inbox / delete -message / maps to views.delete_message etc. At the end of each of these views, it redirects back to / inbox /.

I like the way things are clearly separated by this option. If the user somehow discovers that he is sending a GET request to / inbox / delete -message /, which is some kind of strange situation, though (am I throwing a page with an error? Do I redirect them silently?).

Option 2)

Use the same URL and view for each action and specify the POST parameter that identifies the action. That way, I will have one pretty long look in the Inbox, which will have a lot of if statements checking if request.POST ['action'] == 'delete' or request.POST ['delete'] = is being requested = 'true' or something else.

This option seems less clean to me, but I also feel that it is more common.

What would be preferable to Djangonauts? Or is there another option that is better than any of the above?

+4
source share
4 answers

Modified Option No. 1 is the best approach. Consider this: suppose we are not talking about a web application, but instead just develop a class of incoming messages. What do you like more, a number of methods ( delete_message() , mark_as_spam() , etc.) Or one big method ( do_stuff(action) )? Of course, you would use separate methods.

A separate URL for each action, each with a separate view, is much preferable. If you do not like the redirection at the end, then do not use it. Instead, use the render_inbox(request) method, which returns an HttpResponse, and call the method at the end of each of your views. Of course, redirecting after POST is a good way to prevent duplicate actions and always leaves the user with a constant URL.

It would be even better to use Ajax to hide actions, but it is more active.

+2
source

I do not think that something is wrong with any option, but No. 2 is potentially better in terms of performance. After the action is published, you can display incoming messages without redirecting, so it reduces HTTP traffic.

+1
source

If you are writing a Web 2.0 messaging application, you will use AJAX calls and not load a new page at all. The process will operate as follows:

  • User clicks [delete] message. This button has a javascript action associated with it. This action does the following:

    I. Change the user interface to indicate that something is happening (gray text message or put an hourglass).

    II. Sending a request to / messages / inbox / 1234 / delete. (where 1234 is some identifier that indicates which message)

    III. When a response from the server returns, it should indicate success or failure. Reflect this status in the current user interface. For example, if successful, refresh the Inbox view (or simply delete the deleted item).

On the server side, you can now create a URL handler for each desired action (for example, / delete, / flag, etc.).

If you want to use the even more RESTful approach, you must use the HTTP action yourself to specify the action to execute. Therefore, instead of including delete in your URL, it will be in action. So instead of GET or POST, use DELETE /messages/inbox/1234 . To set the flag for reading, use SET /messages/inbox/1234?read=true .

I don’t know how easy it is to implement this last recommendation in Django, but in general it’s a good idea to use the protocol (in this case HTTP), and not bypass it by encoding your actions into a URL or parameter.

+1
source

I agree that No. 2 is the best approach.

But be careful with overloading submit <input /> various ways - if the user uses it with keyboard input and gets in, he will not necessarily send the <input /> that you expect. Either turn off auto-submit-on-enter, or encode things so that if there is more than one thing that can be sent, there is another field that sets what action should be (for example, the "delete" flag that is checked during request .POST)

If you went from No. 1, I would say that for GET to represent only POST, 405 must be executed (the method is not supported) - or, otherwise, 404.

0
source

Source: https://habr.com/ru/post/1314002/


All Articles