Optimize a drop down for django 1.3 - python

Trying to optimize a django application which is using 1.3. Migrating to latest django is not yet an option, as it's a huge application.
So there's this code in the template:
<select id="item_product">
{% for ip in items %}
<option value="{{ ip.program.id }}/{{ ip.sector.id }}/">{{ ip }}</option>
{% endfor %}
</select>
This seems to generate DB calls for every option - making it pretty slow to just load a page with just a drop-down and a button! Replacing the option values with dummy strings indeed immediately loads the page.
The view is very simple:
#render_to('pick_item.html')
def pick_item(request):
person = request.user.get_profile()
items = ItemProduct.objects.filter(program__in=person.programs)
return {'items': items }
And this code returns pretty fast.
How can I optimize this code for django 1.3 so that the drop-down options have the ids I need more efficiently?

If you only need ID's:
<select id="item_product">
{% for ip in items %}
<option value="{{ ip.program_id }}/{{ ip.sector_id }}/">{{ ip }}</option>
{% endfor %}
</select>
If you need something more complex:
#render_to('pick_item.html')
def pick_item(request):
person = request.user.get_profile()
items = ItemProduct.objects.filter(program__in=person.programs).select_related('program', 'sector')
return {'items': items }

Related

Sort dropdown alphabetically after using jinja2 to build it from a list with for loop & replacing one item with if statement? (Flask app)

I have a python list of files, results, that was created in my flask app.
I create a dropdown select list in my HTML templates by looping through this list. Each file in the list becomes an option with the value and text being the file name. However, I use an if statement to find the query_results.csv file and change the option text to "All Results" instead of using the file name.
<select name="result" method="GET" action="/">
{% for result in results %}
{% if result == 'query_results.csv' %}
<option value="{{ result }}">All Results</option>
{% else %}
<option value="{{ result }}">{{ result }}</option>
{% endif %}
{% endfor %}
</select>
How can I order this select menu alphabetically after I've done this, so that All Results appears at the top where expected? Should I have replaced the item in the list in python and sorted first before building the select menu?

Save the passed value from python in html select tag form

I am passing a string value to select tag in html form and its working properly. But when I load the page again or run the script again, the previously passed values are not shown in drop down list.
In html form, I am passing value like this:
<option value="{{x}}">{{x}}</option>
In python:
x = "Example"
return render_template('example.html', x=x)
can anyone please let me know how to save this value so that it is available for selection in drop down list.
Thanks in advance!
You could set a list, append new option values in it and then pass the list to your html template. Something like this;
# app.py
optionsList = []
optionsList.append('Example')
optionsList.append('Example2')
return render_template('example.html', options=optionsList)
# example.html
{% if options %}
<select name="foo" id="foo">
{% for option in options %}
<option value="{{ option }}">{{ option }}</option>
{% endfor %}
</select>
{% endif %}

Django - Passing multichoice field into POST dictionary

I have a queryset generated in my forms.py file that passes into my template. The template result is a multichoice field based on the queryset. The web browser presentation is correct - it renders the queryset as a drop down choice list that I can make a selection from.
Here is the template code:
<tr><td>{{ form.jury_name | placeholder:'Jury Name' }}</td></tr>
<tr><td><select>
{% for item in form.parent_jury.field.queryset %}
<option name="parent_jury" value="{{ item }}">{{ item }}</option>
{% endfor %}
</select></td></tr>
This is all contained in a table.
When the form is submitted (method = "POST") the POST dictionary has all the correct values for the keys except the parent_jury key which posts a value of ''.
I've worked through several SO solutions on the views.py side, but they don't change the fact that the information available for a clean() is missing the choice field value for 'parent_jury'. How do I get the selected option from the list to attach to the 'parent_jury' key?
I think your rendered HTML is not the way it is supposed to be: the name="..." should be part of the <select> tag, not the <option>s:
<tr><td>{{ form.jury_name | placeholder:'Jury Name' }}</td></tr>
<tr><td><select name="parent_jury">
{% for item in form.parent_jury.field.queryset %}
<!-- remove the name here -->
<option value="{{ item }}">{{ item }}</option>
{% endfor %}
</select></td></tr>
(of course you can remove the <!-- comment --> part (this is only meant to draw attention to this change).

Return the string value of what is selected in the drop down list

I have a list of stops:
<select name="dropdown">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
and a Stops model where one of the attributes is name.
I also have a method find_direction() in my views.py that requires a stop.location input.
How do I record the value of the selected stop.name so I can then get the stop.location to use in views.py?
Thanks!
Currently my method is:
def find_direction(request, stop1name, stop2name):
stop1 = get_object_or_404(Stops, name=stop1name)
stop2 = get_object_or_404(Stops, name=stop2name)
which gives the error: find_direction() missing 2 required positional arguments: 'stop1' and 'stop2name'.. How do I make it record these two variables correctly from the selected drop down list?
Using forms but for some reason..
print(request.GET.get("stop1id", "default_value"))
print(request.GET.get("stop2id", "default_value"))
print(request.method)
print(request.POST.dict())
print(request.GET.dict())
print(request.body)
all return empty
In light of your update, you will most like want to pass the data in a request:
def find_direction(request):
stop1 = get_object_or_404(Stops, name=request.POST.get("stop1name","default_value"))
stop2 = get_object_or_404(Stops, name=request.POST.get("stop2name","default_value"))
This assumes you are sending a POST request from a form back to the server with the stop name data. The dictionary keys stop1name and stop2name should match the names as they are set in your form:
<form action="/get_stop_locations">
<select name="stop1name">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
<select name="stop2name">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
</form>
If you are curious, you were receiving an error because positional arguments for django views are set up as captured bits of a url:
urls.py
urlpatterns = patterns('django_app.views',
url(r'^get_stop_locations/(\w+)/(\w+)$','positional_get_locations'),
)
views.py
def positional_get_locations(request,stop1name,stop2name):
stop1 = get_object_or_404(Stops, name=stop1name)
stop2 = get_object_or_404(Stops, name=stop2name)
Django views requires one argument by default which will store the request object. When there are more views defined, the view expects more arguments to be provided by the url handler. If the url is not set up to pull as many arguments as possible in your urls.py file, you will see this error.
For your case, this requires setting up some tricky URLs however on the client side and I wouldn't recommend it. See this example in the DJango Docs for more information on positional arguments in Django views.
EDIT:
In response to your MultiValueDictKeyError, try:
def find_direction(request):
stop1 = get_object_or_404(Stops, name=request.POST.get("stop1name","default_value"))
stop2 = get_object_or_404(Stops, name=request.POST.get("stop2name","default_value"))
If you have your dropdown located in a form like this:
<form method="post" action="">
<select name="dropdown">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
<input type="submit" />
</form>
You can get the value by defining the following in your views:
def post(self, request, *args, **kwargs):
if 'dropdown' in request.POST:
dropdown_val = request.POST.get('dropdown', False)

Django custom form template

I've a custom template to render my form in my Django website. This code renders the ChoiceFields:
<select id="{{ "id_"|add:field.html_name }}"
class="form-control"
name="{{ field.html_name }}">
{% for id, name in field.field.choices %}
<option value="{{ id }}"
{% if field.value|default_if_none:"" == id %}
selected="selected"
{% endif %}
>{{ name }}</option>
{% endfor %}
</select>
This code works perfectly, when the ChoiceField does not have an initial value. If I sumbit the form, but there's an error in the form (sp I get back to my form, and all the data is in there as I submitted it), the correct choice get the selected="selected" attribute, so it works perfectly fine.
But when I set the default value for the form in my Django view (correctly in the form's init() function, like this: self.fields['card_type'].initial = self.card.card_type_id), this stops working.
If I put manually somewhere in my template the form.value variable it displays the correct integer. In the id, name for-loop there's the same id value. These do not have any whitespace ot something else there. But the code does not works, does not equals to true the self.fields['card_type'].initial = self.card.card_type_id condition.
If I modify the previous code, to print the id, and the field.value instead of the {{name}}, like this: ({{id}}-{{ field.value }}), the following HTML code'll be generated:
<select id="id_card_type" class="form-control" name="card_type">
<option value="3">(3-2)</option>
<option value="2">(2-2)</option>
<option value="1">(1-2)</option>
</select>
There's the id, which is 1, 2, and 3! There's the form.value, which is 2! But there isn't any selected="selected"... Why not working?
Thanks!

Categories

Resources