Pylons and multiple forms per page - python

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...

Related

How to get the page based on the selection in a drop down list in Django

I'm a new on Django. One question confused me about the drop down list in Django. I'd like to know how to change the content in a page based on the selection in the drop down list in Django.
In Model.py I design the fields as:
STATUS_IN_CHOICE = (
('Pending','Pending'),
('Passed','Passed'),
('Failed','Failed'),
)
Status = models.CharField(max_length=10,choices=STATUS_IN_CHOICE,
default='Pending')
The respected result I want is, if I select "Passed" in the drop down list. All the passed cases show in the page. Others are the same.
I have no idea how to code the template and connect with the field now. Cause in my opinion, it's not a forms (post) at all.
You have basically two alternatives, and both of involve the use of javascript.
You either:
need to preload all content at the initial page render, if the content is small and simple, and then use javascript on the drop-down to display the appropriate parts of it.
or to fetch the content with ajax requests depending on the value of the drop-down and render it when it loads.
Neither of the above the use of a model if the drop-down is for display filter only, and no storing is required. You could achieve the same with a simple django form or plain HTML.

Django modelform: Create new related object

I've been searching stack overflow and google for a solution for over an hour now, and I can't seem to find something that, in my opinion, should be easy to obtain (as it's a common use case).
I've checked this thread, and a few others, but I haven't been able to find a real, easy solution:
Django modelform: is inline adding related model possible?
Anyway, say I have a model with three related entities, two foreign keys and a many-to-many related class. Now, I have a ModelForm which displays these in comboboxes and lists, but what I need is that "+" button next to these elements (as seen in the admin interface).
I want the plus to take me to a new form, for that particular entity, allow me to submit the new information, create the database entry, take me back to my original form and have the newly added entity selected in the combobox. I'm really hoping the django ModelForm Meta class has an attribute that I can't seem to find which enables exactly this.
This isn't really a django question.
This has to do with presentation of a particular widget in an html document, and that is governed by either the HTML markup, CSS, or javascript.
Django is a server side application and is primarily responsible for creating a valid http response and receiving a valid http request (of course, there is a lot that happens in the interim and that is why django is so big) but it's not a "one toolkit to kill them all" app.
I think you want to look at bootstrap: http://getbootstrap.com/
Jquery UI: http://jqueryui.com/
Or some combination of the two.
You can also just mark up the document yourself with a stock img or something.
However, if you want to do it exactly how the admin does it, just go into django.contrib.admin and examin the code to figure out how the django developers did it. I believe they are just using Jquery UI and some manual markup to accomplish that.

Implementing Universal Search in a Django Application

We have a large Django application made up of a large number of different views (some of which contain forms). As with most large applications, we use a base layout template that contains the common layout elements across the applications (mainly a header and a footer), which the templates for all of our views extend.
What we are looking to do is create a universal search box in our application, accessible on every page, which allows users to perform searches across the entire application, and want to place the search box inside the header, which involves placing a form inside our base layout template. This means that every view in our application will need to be able to handle the submission of this search form. Once this search form is submitted, we will need to redirect the user to another view containing the search results.
However, we are struggling to come up with a pattern to handle this. Does anyone know of functionality built into Django that will help us to build this? Failing that, can anyone suggest a good strategy for modifying our application so that we can handle this use-case without having to modify a large number of existing views (which we don't have the resources to do at the moment)?
Please note that the focus of this question is intended to be the best way to handle the submission of a form which appears in every view, and not strategies for implementing a universal search algorithm (which we have already figured out).
Ideas Explored So Far
Our first idea was to create a base View class that implements handling the universal search form submission, and have each of our views extend this. However, this is not possible because we already have views that inherit from a number of different Django view classes (TemplateView, ListView, FormView and DeleteView being some examples), and to be able to build our own common view class would mean either writing our own version of these Django view classes to inherit from our own view base class, or re-writing a large number of our views so they don't use the Django view classes.
Our next idea was to implement a mixin that would handle the universal search form submission, in an attempt to add this functionality to all our views in a way that allows us to continue using the different Django view classes. However, this brought to light two new problems: (a) how could we do this without modifying each of our views to become a form view, and (b) how can we do this in a way that allows the form handling logic to play nicely when mixed in to existing FormViews?
This seems like such an obvious question that maybe I'm overlooking something. But as others have said your universal search form should not make a POST request to the view that rendered the current page.
Each html form has an action attribute. The attribute of your search form should point towards an URL. Probably something like /search. That url would have a view behind it that handled the POST request from the form and returned the search results. Django has URL template tags to make this easy. {% url 'myapp.views.search' %} will give you the correct url for the search view function if it lived inside the views module in myapp. So the relevant bit of html in your base template would be something like:
<form action="{% url 'myapp.views.search' %}">
<input type="text" name="qs" placeholder="Search">
</form>
If you are planning on displaying the search results on a new page there is absolutely no need to return JSON or anything like that. Just have a search view that looks like this
def search(request):
query = request.POST.get('qs', '')
results = SomeModel.objects.filter(name=query) # Your search algo goes here
return render(request, 'search_results.html', dict(results=results))
Instead of handling the form submission on every view of the application, you can implement a separate view (endpoint), which handles all the search queries. (an endpoint which returns JSON result) since you dont want to add overhead of rendering the whole page with that view. So the search query (which client side AJAX performs to the webserver) will return JSON response, and the Javascript can render that response. This way you can keep the search view isolated from the rest of the views. (Django REST will be helpful in this case)
And this search form will be included in your base template, so your search box is accessible from the entire application, and it submits to the same view. And the AJAX function will handle the server response for rendering it.
It seems like you just need to create another SearchView which takes the query and displays the results. I am not sure if the results have to be displayed differently depending on which page the search has been performed from but it does not seem like.
The form would not have anything to do with the other views. You could just hard code it in the base template.

Processing forms that generate many rows in DB

I'm wondering what the best approach to take here is. I've got a form that people use to register for a class and a lot of times the manager of a company will register multiple people for the class at the same time. Presently, they'd have to go through the registration process multiple times and resubmit the form once for every person they want to register.
What I want to do is give the user a form that has a single <input/> for one person to register with, along with all the other fields they'll need to fill out (Email, phone number, etc); if they want to add more people, they'll be able to press a button and a new <input/> will be generated. This part I know how to do, but I'm including it to best describe what I'm aiming to do.
The part I don't know how to approach is processing that data the form submits, I need some way of making a new row in the Registrant table for every <input/> that's added and include the same contact information (phone, email, etc) as the first row with that row. For the record, I'm using the Django framework for my back-end code.
What's the best approach here? Should it just POST the form x times for x people, or is there a less "brute force" way of handling this?
Django includes FormSet for dealing with exactly these challenges. Using a FormSet you can create multiple forms for creating or updating information. There's even possible to generate the FormSets from a Model. http://docs.djangoproject.com/en/dev/topics/forms/formsets/ and http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#id1 are great resources.
Now, for creating more forms on the fly, you need some javascript magic. I've done this on work projects using jQuery which made it a lot simpler. The basic idea is create a new form with the correct inputs and change the hidden metadata in the formset form so it will now how many forms to process. The admin implements this when using multiple inline forms so I suggest looking there for code as it is a bit tricky to get right.

Rendering common session information in every view

I'd like to output some information that depends on session data in Django. Let's take a "Login" / "Logged in as | Logout" fragment for example. It depends on my request.session['user'].
Of course I can put a user object in the context every time I render a page and then switch on {% if user %}, but that seems to break DRY idea - I would have to add user to every context in every view.
How can I extract a fragment like that and make it more common?
Use template inheritance to derive all of your templates from a common base that suitably uses the common parts of the context, and make all your contexts with a factory function that ensures the insertion in them of those common parts.
Are you trying to make certain areas of your site only accessible when logged on? Or certain areas of a particular page?
If you want to block off access to a whole URL you can use the #login_required decorator in your functions in your view to block certain access. Also, you can use includes to keep the common parts of your site that require user login in a separate html that gets included, that way you're only writing your if statements once.
You may want to use a context processor that includes logic and place it into a variable you can use in any of your pages without adding it to each call.
See more info at How to pass common dictionary data to every page in django

Categories

Resources