The order of dictionary is varied each time although using OrderedDict.
I wrote in views.py
from collections import OrderedDict
from django.shortcuts import render
import json
def index(request):
with open('./data/data.json', 'r') as f:
json_dict = json.loads(f.read())
json_data = OrderedDict()
json_data = json_dict
return render(request, 'index.html', {'json_data': json_data})
and I wrote in index.html
<html>
<head>
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/chosen/1.8.2/chosen.jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/chosen/1.4.2/chosen.jquery.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/chosen/1.4.2/chosen.css">
</head>
<body>
<select id="mainDD" data-placeholder="Choose" class="chzn-select" style="width:600px;">
{% for i in json_data.items.values %}
<option>{{ i }}</option>
{% endfor %}
</select>
<select name="type" id="type1">
{% for j in json_data.type1.values %}
<option>{{ j }}</option>
{% endfor %}
</select>
<select name="type" id="type2">
{% for k in json_data.type2.values %}
<option>{{ k }}</option>
{% endfor %}
</select>
<select name="type" id="type3">
{% for l in json_data.type3.values %}
<option>{{ l }}</option>
{% endfor %}
</select>
<select name="type" id="type4">
{% for m in json_data.type4.values %}
<option>{{ m }}</option>
{% endfor %}
</select>
</script>
</body>
</html>
Variable of i&j&k&l&m has result of json_data,but this dictionary of json_data is not the order.For example i has {'items': [{'---': '---', ‘A’: ‘a’, ‘B’: ‘b’, ‘C: ‘c’, ‘D’: ‘d’}]} but the order of drill down is b=>c=>d=>a.I want to show a =>b=>c=>d .I think this can be done by using OrderedDict() but it is wrong.How should i fix this?What should I write it?
All you've done is overwrite your parsed JSON with an OrderedDict object; that doesn't do anything useful at all.
Instead, as the documentation shows, you can pass that class as the object_pairs_hook parameter:
json_dict = json.loads(f.read(), object_pairs_hook=OrderedDict)
Your idea is correct. Using OrderedDict will preserve the order of the items in the dictionary. However there is an error in your code:
json_data = OrderedDict()
json_data = json_dict
First you initialize json_data as OrderedDict, but in the second statement you override the variable and assign it the value of json_dict.
Daniel Roseman was faster than me and gave you better answer, I'd just naively done this:
json_data = OrderedDict(json_dict)
Related
I am working on a project for school, and am having a lot of trouble with Templates in Django.
My code is below, the first block is Python in a function, bear in mind I removed a lot for easy viewing.
amounts = [('None ',), ('1 1/2 oz',), ('1 oz',), ('1/2 oz',), ('1/2 ml ',), ('15 ml',), ('35 ml',), ('splash',), ('6 splashes',), ('10 dashes',), ('25 ml',), ('3 slices',)]
data = {
'amounts': amounts,
'ingredients': ingredients,
}
amount1 = request.GET.get('amount1')
print(amount1)
return render(request, 'addcocktail.html', {'data': data})
This block is my HTML file:
<select name="amount1" id="amount1">
{% for key, value in data.items %}
{% if key == 'amounts' %}
{% for amount in value %}
<option value = {{amount}}> {{ amount.0 }}</option>
{% endfor %}
{% endif %}
{% endfor %}
</select>
When I select 1 oz on the website, amount1 is printed as:
1
which is the first half of the string in the tuple: '1 oz'.
I was wondering if anyone knew what the problem here is.
Thank you Chillie, I solved it by removing the value = {{ amount }}, so it then takes the content that is displayed to the user as the value, the final HTML is:
<select name="amount1" id="amount1">
{% for key, value in data.items %}
{% if key == 'amounts' %}
{% for amount in value %}
<option> {{ amount.0 }}</option>
{% endfor %}
{% endif %}
{% endfor %}
</select>
I assume the value attribute only takes strings as an answer, so it was only taking the first half of the string.
I want to setup filter in templates
I have filtered objects that I wanted, and now how can I setup the template?
So I can filter objects through dropdown?
What I'have done so far
#login_required
def list_jobs(request):
assigned_jobs = Job.objects.filter(assign_to=request.user).order_by('-date_created')
created_jobs = Job.objects.filter(user=request.user).order_by('-date_created')
completed_jobs = Job.objects.filter(completed=False).order_by('-date_completed')
return render(request, 'jobs/list.html', {'created_jobs': created_jobs, 'assigned_jobs': assigned_jobs,
'completed_jobs': completed_jobs})
Example Something like this:
<select id="id">
{% for i in assigned_jobs %}
<option value="{{ i.id }}">{{ i.name }}</option>
{% endfor %}
</select>
I tried:
list1 = [{"username": "abhi", "pass": 2087}]
return render_template("file_output.html", list1=list1)
In the template:
<table border=2>
<tr>
<td>
Key
</td>
<td>
Value
</td>
</tr>
{% for dictionary in list1 %}
{% for key in dictionary %}
<tr>
<td>
<h3>{{ key }}</h3>
</td>
<td>
<h3>{{ dictionary[key] }}</h3>
</td>
</tr>
{% endfor %}
{% endfor %}
</table>
The above code is splitting each element into multiple characters:
[
{
"
u
s
e
r
...
I tested the above nested loop in a simple Python script and it works fine but not in Jinja template.
Data:
parent_list = [{'A': 'val1', 'B': 'val2'}, {'C': 'val3', 'D': 'val4'}]
in Jinja2 iteration:
{% for dict_item in parent_list %}
{% for key, value in dict_item.items() %}
<h1>Key: {{key}}</h1>
<h2>Value: {{value}}</h2>
{% endfor %}
{% endfor %}
Note:
Make sure you have the list of dict items. If you get UnicodeError may be the value inside the dict contains unicode format. That issue can be solved in your views.py.
If the dict is unicode object, you have to encode into utf-8.
As a sidenote to #Navaneethan 's answer, Jinja2 is able to do "regular" item selections for the list and the dictionary, given we know the key of the dictionary, or the locations of items in the list.
Data:
parent_dict = [{'A':'val1','B':'val2', 'content': [["1.1", "2.2"]]},{'A':'val3','B':'val4', 'content': [["3.3", "4.4"]]}]
in Jinja2 iteration:
{% for dict_item in parent_dict %}
This example has {{dict_item['A']}} and {{dict_item['B']}}:
with the content --
{% for item in dict_item['content'] %}{{item[0]}} and {{item[1]}}{% endfor %}.
{% endfor %}
The rendered output:
This example has val1 and val2:
with the content --
1.1 and 2.2.
This example has val3 and val4:
with the content --
3.3 and 4.4.
{% for i in yourlist %}
{% for k,v in i.items() %}
{# do what you want here #}
{% endfor %}
{% endfor %}
Just a side note for similar problem (If we don't want to loop through):
How to lookup a dictionary using a variable key within Jinja template?
Here is an example:
{% set key = target_db.Schema.upper()+"__"+target_db.TableName.upper() %}
{{ dict_containing_df.get(key).to_html() | safe }}
It might be obvious. But we don't need curly braces within curly braces. Straight python syntax works. (I am posting because I was confusing to me...)
Alternatively, you can simply do
{{dict[target_db.Schema.upper()+"__"+target_db.TableName.upper()]).to_html() | safe }}
But it will spit an error when no key is found. So better to use get in Jinja.
**get id from dic value. I got the result.try the below code**
get_abstracts = s.get_abstracts(session_id)
sessions = get_abstracts['sessions']
abs = {}
for a in get_abstracts['abstracts']:
a_session_id = a['session_id']
abs.setdefault(a_session_id,[]).append(a)
authors = {}
# print('authors')
# print(get_abstracts['authors'])
for au in get_abstracts['authors']:
# print(au)
au_abs_id = au['abs_id']
authors.setdefault(au_abs_id,[]).append(au)
**In jinja template**
{% for s in sessions %}
<h4><u>Session : {{ s.session_title}} - Hall : {{ s.session_hall}}</u></h4>
{% for a in abs[s.session_id] %}
<hr>
<p><b>Chief Author :</b> Dr. {{ a.full_name }}</p>
{% for au in authors[a.abs_id] %}
<p><b> {{ au.role }} :</b> Dr.{{ au.full_name }}</p>
{% endfor %}
{% endfor %}
{% endfor %}
I'm learning Python. I would like display results based on multiple selections from dropdowns.
The following code is working and returning the correct results for one dropdown. I would like to add at least one more dropdown, hopefully multiple, but I cannot fathom how to achieve passing and returning the multiple vars.
Form code
<p> <form method="get" action="">
<select name="search3">
{% for cs in course_list %}
<option value="{{ cs.pk }}">{{ cs.name }}</option>
{% endfor %}
</select>
<br/><br/>
<input type=submit value="Find staff" />
</form>
</p>
{% if employee_list %}
{{ employee_list.count }} employees matching : <strong>{{ course }}</strong><br/><br/>
{% for e in employee_list %}
{% if not e.img1 %}
<img src="/media/images/null_image.png" width="35" title="{{ e.first_name}} {{e.surname }}" />
{% else %}
<img src="{{ e.img1.url }}" width="50" title="{{ e.first_name}} {{e.surname }}"/>
{% endif %}
<a href="/employee/{{ e.slug }}" target="_blank" rel="popup" title="Details...<br />
{% for det in employee_list.employeedynamic_set.all %}
{{ det.mobile }}<br />
{{ det.depot }}<br />
{% endfor %}
"> {{ e.first_name }} {{ e.surname }}</a><br/>
{% endfor %}
{% else %}
<p>No employees matched: <strong>{{ course }}</strong></p>
{% endif %}
views.py code
# function to list training courses and participating uindividuals.
def CourseView(request):
course_list = Course.objects.all().order_by('name')
if 'search3' in request.GET:
search3 = request.GET['search3']
course = Course.objects.get(pk=search3)
else:
search3 = None
course = None
return render_to_response("course_display.html", {'course':course, 'course_list': course_list, 'search3': search3 })
Is it possible to add an another dropdown option or even multiple dropdown options and get a result. Or am I barking up the wrong tree?
UPDATE.
In order to pass one or multiple variables back to my function the code is simply the following
def CompetencyCheck(request):
course_list = Course.objects.all()
if 'search3' in request.GET:
search3 = request.GET.getlist('search3')
course = Course.objects.filter(id__in=search3).distinct().order_by()
.get() allows only the last variable passed from the web page form to be read/passed back to the function.
On the other hand, the .getlist() allows one or multiple vars to be passed back. Great, part the of problem solved.
The list of names being returned is unique in that if var1 returns 4 names and var2 returns 8 names and both vars have one common name, a list of 11 names in returned.
I want only the common names to both vars returned, i.e. 1 name to be returned.
Any ideas?
request.GET in your view is a dictionary; by doing request.GET['search3'] you're just accessing the value of its search3 key. So in your template, you should be able to just add other <select> elements with their own names and retrieve their submitted values from request.GET in the same way.
you can query using course_list only.
for example:
course_list = Course.objects.all().order_by('name')
var1 = request.POST.get('var1')
if var1:
course_list = course_list.objects.filter(some = var1)
var2 = request.POST.get('var2')
if var2:
course_list = course_list.objects.filter(some = var2)
Have a form where user can change name on attribut Name and change which attribut a is connected to (attribut b).
Template:
"<form id="form1" name="form1" method="post" action="/define_a/{{c.id}}/edit/">
{% csrf_token %}
{% endblock %}
{% block buttons %}
<p><input type="submit" value="Save" /> Cancel
</p>
{% endblock %}
{% block a_rows %}
{% for a, a_form in a_list %}
<tr><td><img class="icon" src="{{images_dir}}/delete-icon.png"
onclick="javascript: return confirmDelete_name('Are you sure?
This will delete the stuff and all associated information.
The removal happens immediately and cannot be undone.', '{{a.id}}', 'delete');" />
</td><td>{{a_form.name}}</td>
<td>
<select name= "test">
<option value = "Null">None</option>
<option value = "{{a_form.id}}" selected>{{a.b}}</option>
{% for a, a_form in a_list %}
<option value = "{{a_form.id}}">{{a.name}}</option>
{% endfor %}"
View:
Checking that it is a post and that it is valid.
post = [myForm(request.POST, instance = test) for a in a's];
for p in post :
if not new_t.b == p:
if p == 'None':
new_t.b = None;
else:
new_t.b = p;
But i can't get all the values from the dropdown in the post.
I get all a.name in but only one value from the dropdown, sometimes I don't get any value at all.
Any ideas?