Distinguishing post request's from possible poster elements - python

So, what issue im running into is how do i know what element of my page made a post request? I have multiple elements that can make the post request on the page, but how do i get the values from the element that created the request? It seems like this would be fairly trivial,but i have come up with nothing, and when doing quite a few google searches i have come up with nothing again.
Is there any way to do this using Bottle?
I had an idea to an a route for an sql page (with authentication of course) for providing the action for the form and use the template to render the id in the action, but i was thinking there had to be a better way to do this without routing another page.

You could add a hidden input field to each form on the page with a specific value. On the server side, check the value of this field to detect which form the post request came from.

Related

Django rest framework: correctly handle incoming array of model ids

I have a question about REST design in general and specifically what the best way to implement a solution is in Django Rest Framework. Here it the situation:
Say I have an app for keeping track of albums that the user likes. In the browser, the user sees a list of albums and each one has a check box next to it. Checking the box means you like the album. At the bottom of the page is a submit button.
I want the submit button to initiate an AJAX request that sends tp my API endpoint a list of the ids (as in, the Djano model ids) of the albums that are liked by the user.
My question is, is this a standard approach for doing this sort of thing (I am new to web stuff and REST in particular). In other words, is there a better way to handle the transmission of these data than to send an array of ids like this? As a corollary, if this is an alright approach, how does one implement this in Django Rest Framework in a way which is consistent with its intended methodology.
I am keeping this question a little vague (not presenting any code for the album serializer, for example) intentionally because I am looking to learn some fundamentals, not to debug a particular piece of code.
Thanks a lot in advance!
Consider the upvote button to the left. When you click it, a request may be sent to stackoverflow.com/question/12345/upvote. It creates an "action resource" on the db, so later you can go to your user profile and check out the list of actions you took.
You can consider doing the same thing for your application. It may be a better user experience to have immediate action taken like SO, or a "batch" request like with gmail's check boxes.

Web API and rendering template, should they in the same function call?

I am new on web development.
I am now implementing a simple create/edit user form with a submit button.
I would like to know the better practice to implement this.
I have already define this kind of web api
URL Method Description
/users/ GET Gives a list of all users
/users/ POST Creates a new user
/users/<id> GET Shows a single user
/users/<id> PUT Updates a single user
/users/<id> DELETE Deletes a single user
My first approach:
i create two new "/user/add" and "/usr/edit" function,
which similar to
app.route("/users/edit")
def edit_user(){
....
....
call the internal api /user/ with a "put" method
....
render_template("edit.html")
when I click the submit the button, the i call the above internal api /users/ ,method=PUT,
and render the final template.
My second approach:
in my internal api /user/, i try to read the http header to see if i want a html template or json text and return back to user
Say, again when i want to create a edit form, instead of calling /user/edit , i call /user/, with a PUT method
def put(self, id):
//see the header of that request
if header == html
render_template("edit.html", .....)
if header == json
update the record
#
my question , basically, i don't know if "/user/add" "/user/edit" route is necessary to make a form, or we can just simple embedded into /user/ api with different "post" or "put" method.
the idea is coming from here , from flask, pluggable view, which i am wondering how to make a better implementation
Or is that a better way to do it???
Thanks a lot.
I would choice your first approach because than your URLs are clear and logical. Also you split your frontend (Website with forms) and backend (API) which is in testing very helpful. A normal web browser makes only GET and POST requests to a website so it is very difficult to render template by a PUT request for the user because the user is normally not able to start a put request.

Django: How do I redirect to page where form originated

In my Django app I have multiple pages displaying a link that loads a new page displaying a form. When the form is submitted, what is the cleanest way to redirect to the originating page from which this form was accessed?
originating page -> form page -> originating page
Using a next variable seems unellegant since I have to set it as a GET variable on the originating page link, and then set it as a hidden POST variable in my form? Any other ideas would be appreciated.
There are a couple of options, all with the cons and benefits ofcourse.
passing the originating page withi POST/GET
storing the originating page in the session (won't work with multiple tabs obviously)
storing the originating page in a cookie (won't work with multiple tabs either)
if it's a single page, redirect to the referrer. Doesn't seem possible in your case
Personally I think using a next parameter is your best option, but do remember to secure it (only relative urls, no javascript stuff, csrf framework) so you won't have any security problems with it.
WoLpH already listed the resonable possibilities and pointed to (probably) the best of them as a solution. So I will only elaborate on it.
If you need to handle this: originating page -> form page -> originating page then in reality it will look like this: originating page --[GET]--> form page --[POST/submision]--> form page(2) --[GET/redirect]--> originating page. This means, that form page(2) stage has to somehow know where to redirect user and the only reasonable choices you have here is to use session (with the drawback mentioned by WoLpH) or to pass it in POST, possibly as a hidden field.
Regarding the first GET and passing next URL into form page, you can either pass it in the query string (which you find unelegant), or you can extract it from HTTP_REFERER header - which won't work for more paranoid users like me.
You can also do a mixed stuff here, i.e. add next=<next-URL> into the query string if and only if user hasn't turned off HTTP_REFERER in her browser. Then most users won't see any ugly stuff in URLs.
Note that all these things can be automated, i.e. you can write your links as:
<a href="{% url myform %}?{% inject_next_url %}">
When inject_next_url injects sth like: next={{ context['request'].get_full_path() }} only if HTTP_REFERER is not present.
Then, in form handler you can use some generic extract_next_url(request) function, that looks for next URL in one of: query string, HTTP_REFERER, request.POST, or more consise - in one of: HTTP_REFERER, request.REQUEST
Another option might be to create separate URL conf that resolve to the same view, and passing in the source view as a kwargs to the view.

URLs and side effects (Django)

I'm wondering if it's considered okay (particularly, in Django) to have a URL that's only intended for actions with side effects, that's only intended to be accessed by POST, and that is basically invisible to the user. Let's say, for the sake of making this concrete, I have a little messaging system on my site, and from their inbox, a user should be able to do a bunch of things like:
Delete a message
Mark a message as read
Report a message as spam
With all of those things causing a page refresh, but leading back to the same page. I'm wondering how to design my URLs and views around this. I see (at least) two options, and I have no idea which is more idiomatic.
Option 1)
Have a separate URL and view for each action. So, /inbox/delete-message/ maps to views.delete_message, and so on. At the end of each of those views, it redirects back to /inbox/.
I like the way things are clearly separated with this option. If a user somehow finds themselves sending a GET request to /inbox/delete-message/, that presents a sort of weird situation though (do I throw up an error page? silently redirect them?).
Option 2)
Use the same URL and view for each action, and have a POST parameter that identifies the action. So I would have one rather long inbox view, which would have a bunch of if statements testing whether request.POST['action'] == 'delete', or request.POST['delete'] == 'true' or whatever.
This option feels less clean to me, but I also feel like it's more common.
Which would be preferred by Djangonauts? Or is there another option that's better than either of the above?
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.
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.
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.
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.

Pylons and multiple forms per page

I've got a web page I'm generating with Pylons and the evoque templating tool. I'm trying to generate a page with multiple forms per page (one form is part of a base template that becomes part of every page). I'm having a problem as I seemingly can only get the form element values for one form; whenever I try to get the value from the base template, I get nothing back. Is there a way in Pylons to get a form element from a form by name? I'm using the request.params("variable_name") style that is standard in Pylons.
Thanks in advance for your help!
Doug
You will only get the form values for the form that was posted in the request(ie: whichever submit button the user clicked), that's how html works.
Yes (to iterate Tom's answer), HTML is designed to explicitly only allow a single form to be submitted at a time. Plus, forms may not be nested, so no confusion possible there.
However, a single form may contain multiple submit buttons. So, you may if you really want to organize your page as one big single form, and so submitting will submit all the values each time. You will need to take care then that there are all field names are distinct -- so, not convenient if you have a repetition of "item" forms, in which case it should be a lot cleaner to have a form per item...

Categories

Resources