Submitting Multiple Forms At The Same Time (Edit Profile Page) - python

My question I suppose is rather simple. Basically, I have a profile. It has many variables being passed in. For instance, name, username, profile picture, and many others that are updated by their own respective pages. So one page would be used to update the profile picture, and that form would submit data from the form to the handler, and put() it to the database. What i'm trying to do here, is put all of the forms used to edit the profile on one single page at the same time.
Would I need one huge handler to deal with that page? When I hit 'save' at the bottom of the page, how do I avoid overwriting data that hasn't been modified? Currently, say I have 5 profile variables, they map to 5 handlers, and 5 separate pages that contain their own respective form.
Thanks.

I've used django on most of my webapps, but the concept should be the same; I use ajax to send the data to the backend whenever the user hits submit (and the form returns false) so the user can keep editing it. With ajax, you can send the data to different handlers on the backend. Also, using jQuery, you can set flags to see if fields have been changed, to avoid sending the ajax message in the first place. Ajax requests behave almost exactly like standard HTTP requests, but I believe the header indicates AJAX.
If you're looking at strictly backend, then you will need to do multiple "if" statements on the backend and check one field at a time to see if it has been changed. On the backend you should still be able to call other handlers (passing them the same request).

Related

Best way to handle complex data sent to tornado by ajax

This is a design question, not a code question. Title sucks, the problem isn't very describable in a few words.
I have a user database (mongodb). I built a front-end table in javascript that allows admin to see all users, edit their information, add new ones and delete them. All changes are stored in a javascript object until the admin clicks a Save button, then they are ajaxed to the server. The object looks like this:
{
"new": [<ids of new users>],
"deleted": [<ids to be deleted from database>],
"edited": {<edited fields of existing users and all fields of new users>}
}
I need to send this to the server and write changes into the database. There are multiple ways to do this.
I send the whole object to the server, where it will be handled by one RequestHandler. I need to also have separate handlers to handle the separate "add", "delete" and "edit" operations, because they will be needed elsewhere, so I put the actual functionality into functions that can be called from more handlers so I don't repeat myself too much.
I send three ajax requests for new, deleted and edited. In this case, new would carry the data, not only the ids. Each is handled by the separate handler. This is easier for backend, because the one big handler from option 1 doesn't have to exist, but I don't know if it is a good idea to make multiple ajax requests like this.
I ajax the one big object to one handler and then using HTTPClient I send requests from the handler to the separate handlers to do their thing. Saves ajax requests and the backend implementations are a bit cleaner, but the actual server side request sending seems dirty to me.
Another way I don't see.
What do you think?

ways to avoid previous reload tornado

I have two forms, when I submit form#1 I get some corresponding file, but when I submit form#2 thenafter, the corresponding file gets shown but form#1 goes empty. So basically I want some thing like a SPA(e.g angular) but I am taking form#1 and form#2 as separate requests routes and each render my index.html every time, so form#2 is wiped off when I submit form#1 and vice-versa.
I dont want a working code but any ideas on how I do that with Tornado (not angular, or say Tornado + Angular ? )
I think one way for example is to handle these requests via a controller and do an AJAX post to corresponding Tornado Handler, which after the file is rendered, displays / serves the very file back again. But this uses AngularJS as a SPA. Any other solution possible?
Thanks in Advance
This is not really a Tornado question, as this is simply how Web works.
One possible solution is to have only one form, but display its fields so that they look like two forms; in addition, have two separate submit buttons, each with its own name and value. Now, when you click on either button the whole form will be submitted, but in the handler you can process only the fields associated with the clicked button, while still displaying values in all the fields.

Django Pagination, User selected entry amount error

I have a page with a form that a user enters information to help filter a queryset when they press submit. Upon submission, they are brought to a results page that displays this filtered queryset. I have pagination set up with Django as well as an interactive drop down where the user can select how many entries of the queryset they would like to view per page. I got all this working, but the issue that I am having is that to make it work I need a global queryset object. I've run into issues when several threads are using the page at once so I am trying to find alternative options than using a global, but still allowing the interactive dropdown and pagination.
When I try to remove the global and click on the second or another subsequent page, the query seems to get wiped out and I get an error saying a None object cannot be iterated over. Any tips on alternatives I can try that will avoid this error? Thanks!
You're going about it wrong - rather than trying to remember the state of the queryset for each user and paging based on that, instead set your user page up to request the page it wants and request it from the server.
You could do this in a lot of ways, but something like Tastypie or django rest framework can give you an easy way to develop a page based api and Datatables or similar can allow you to filter and request the pages using Ajax.

Better way of passing form parameters into hidden form in Pyramid

In a previous question, I was trying to figure out the right strategy for to passing data between forms in Pyramid. Based on the answer I received, I decided the approach of using a hidden form.
I started implementing this and think there must be a better way of passing along the data. Specifically, passing parameters through the url results in a tuple that is messy to parse.
I want it to be general enough to not to know what parameters the form has and also it needs to handle file fields as well.
How I'm currently attempting to pass the form data to the confirmation page:
#view_config(renderer="templates/derived/load/error.mak", route_name='process_model_route')
def process_model(self):
#processing logic and validaton, failiure in validation sends user to error.mak
return HTTPFound(route_url('confirm_model_route', self.request, fparams=self.request.POST))
Route: config.add_route('confirm_model_route', 'rnd2/model/confirm/*fparams')
#view_config(renderer="templates/derived/confirm/model.mak", route_name='confirm_model_route')
def confirm_model(self):
form_dict = self.request.matchdict['fparams']
#need to decode and pass to template
return dict({'load_route':load_route, 'form_dict':form_dict})
The confirm/model.mak template would contain the hidden form.
The idea with this method is:
Client visits page.
Server renders the form.
Client fills in form and POSTs to URL.
Server renders a new page that contains a hidden form with all of the data it just received in the POST.
Client POSTs to a URL, confirming the submission.
Server persists the data from the hidden form and redirects.
Now depending on usability, it's up to you to decide how many different URLs you actually want here and how many views in Pyramid. You have to think about what happens with invalid data?
Notice in the outline above, once the user POSTs the form to a URL, that URL must return the confirmation page containing a hidden form. If you try to redirect the user to a confirmation page instead, you must persist the data somehow, either in a session or through the hack you showed in your example (shoving all of the data into the GET). The second solution is very bad because it abuses the true purpose of GET in HTTP.
There is also the convention that every POST should result in a redirect to avoid a client submitting the form multiple times. With this in mind you might consider the simple solution of rejecting POSTs that do not have a "confirmed" flag and simply setting the "confirmed" flag in javascript after prompting the user. This allows you to keep your form handling logic simple.
If you don't want to rely on javascript and you don't want to persist the form data in a session, then you run into the issue of not redirecting after the first POST but other than that it should be simple from the outline above.

Pass variables to a "success" page after processing a form in Django

Is there anyway to pass context variables to a redirect response? I want to redirect a user to a success page after they submit a form, but I don't want the success page to be just a static html file. I need to display extra information based on the form data.
I have looked at this question, but the solution presented there simply renders a different file at the same url. I'd like to redirect the user so that hitting refresh at the page won't submit duplicate entries into the application.
Right now the only thing I have been able to use with some success is redirecting to a url while passing it GET variables as described here. That just seems like a bit of a hack, and was just wondering if there is any better solution...
Thank You
The way I see it you have three options:
Use GET variables in the redirect.
Store something in the session.
If you are creating an object using the form that was submitted, put the id of that object in the redirect url and use it in the new view.
The limitation you are running up against is that http is stateless, not something inherent in django.
How about storing your values in a session, then have the redirected page pick up the values from there?

Categories