I'm trying to create some graphics in my template with data from my models. I'm doing a survey app. Each survey has some questions, and each question has some answers. The user answer each question. So I count the answer for each question. I want to plot these answers in my template.
I'm using this view to count the data and render to template:
def SurveyResults(request, id):
user = request.user
if user.is_authenticated():
quest_survey = Survey.objects.get(id=2)
quests = quest_survey.questions()
graphic = {}
graphic_id = 1
if quests:
for quest in quests:
a1 = AnswerSelect.objects.filter(question_id=quest.id, body = "answer 1").count()
a2 = AnswerSelect.objects.filter(question_id=quest.id, body = "answer 2").count()
a3 = AnswerSelect.objects.filter(question_id=quest.id, body = "answer 3").count()
a4 = AnswerSelect.objects.filter(question_id=quest.id, body = "answer 4").count()
graphic[str(graphic_id)] = [['answer1', a1], ['answer2', a2], ['answer3', a3], ['answer4', a4] ]
graphic_id += 1
return render(request, 'results.html', locals())
else:
msg = "A Survey não possui questões"
return HttpResponseRedirect('profile.html')
else:
msg = "Usuario ou senha digitados incorretamente"
return HttpResponseRedirect('home.html', {'msg': msg})
The question is, how can I get the values of graphic["1"],...,graphic["n"] in my template?
I'm trying to do this:
{% if graphic %}
{% for g in graphic %}
{% for item in g %}
{{ item }}
{% endfor %}
{% endfor %}
{% endif %}
But instead of the data, I only get the value of the ids: 1,2,...,n
Use items function to display the keys and values of the dictionary in template:
{% for key, value in graphic.items %}
{% for item in value %}
{{ item }}
{% endfor %}
{% endfor %}
Related
My cart view.
I have passed context on return but it doesn't appear on the templates. If i print the
def cart(request):
total = 0
quantity = 0
cart_items = None
tax = None
grand_total = None
try:
cart = Cart.objects.get(cart_id=_cart_id(request))
cart_items = CartItem.objects.filter(cart=cart, is_active=True)
for cart_item in cart_items:
total += (cart_item.product.price * cart_item.quality)
quantity = cart_item.quality
tax = (total / 100) * 2
grand_total = total + tax
except:
pass
context = {
'total': total,
'quantity': quantity,
'cart_items': cart_items,
'tax': tax,
'grand_total': grand_total,
}
return render(request, 'c.html', context)
Html Template. Here I created a for loop to get items from the array. But It doesn't show any objects from the array. But always print "Item" string for each object.
{% extends 'base.html' %}
{% load static %}
{% block content %}
{% for item in cart_items %}
<h1>item.product.product_name </h1>
{% endfor %}
{% endblock %}
You code is not correct i think. Try this:
{% extends 'base.html' %}
{% load static %}
{% block content %}
{% for item in cart_items %}
{{item.product.product_name}}
{% endfor %}
{% endblock %}
I have a questionnaire, containing many questions with their answers. My main objective is to create a webpage where I can show the details of a questionnaire with the list of rules (question/answer) and in the bottom of the page I want to call the create rule page:
def create_rule_view(request, id, sc_id):
if request.method == "POST":
input = InputForm(request.POST)
answer = AnswerForm(request.POST)
rule = RuleForm(request.POST)
if rule.is_valid() and input.is_valid() and answer.is_valid():
r = rule.save()
i = input.save(commit=False)
a = answer.save(commit=False)
i.rule_id = r
i.save()
a.rule_id = r
a.save()
question = input.cleaned_data["patterns"]
else:
input = InputForm()
answer = AnswerForm()
rule = RuleForm()
return render(request, "rule/create_rule.html", {
'rule': rule,
'input': input,
'answer': answer
})
def detail_scenario(request, id, sc_id):
object = get_object_or_404(Scenario, id=sc_id)
# TODO : add rule in the same view
create_rule_div = create_rule_view(request, id, sc_id)
print("content", create_rule_div)
context = {
'scenario': object,
'create_rule_div': create_rule_div
}
return render(request, "scenario/detail_scenario.html", context)
This is rule_create.html:
{% block content %}
<form method="POST"> {% csrf_token %}
<h2>Create Rule</h2>
{{ rule.name}}
{{ input.patterns }}
{{ answer.text }}
<input type="submit" value="Save Rule"/>
</form>
{% endblock %}
This is detail_senario.html:
{% block content %}
<h2>Scenario {{ scenario.id }}</h2>
<p>Scenario for : {{ scenario.chatbot_id }}</p>
<p>Name: {{ scenario.name }}</p>
<p>Description: {{ scenario.description }}</p>
<p>State: {{ scenario.state }}</p>
{% for rule in scenario.rule_ids.all %}
<li>{{ rule }}</li>
{% endfor %}
<div>{% block rule %}
{{ create_rule_div.content }}{% endblock %}
</div>
{% endblock %}
when I call url of detail_scenario I got an html code in navigator like this:
How can I fix this?
Thanks.
I have two models with one having a foreign key to the other as such:
Models:
class WhoAmI(models.Model):
name = models.CharField(max_length=200)
company = models.CharField(max_length=200)
def __str__(self):
return self.name
class SolarClient(models.Model):
name = models.CharField(max_length=200)
client_owner = models.ForeignKey(WhoAmI, on_delete=models.CASCADE, related_name='solarclients')
addr = models.CharField(max_length=200)
city = models.CharField(max_length=200)
state = models.CharField(max_length=200)
email = models.EmailField()
I am trying to simply display an html table showing each client a salesperson has, with the salesperson listed first with a table of clients below their name.
The only way I could figure out how to do this was to create a dictionary using the code shown below.
class Homeowners(DetailView):
def get(self, request, **kwargs):
salespersons = WhoAmI.objects.all()
homeowners = SolarClient.objects.all().order_by("client_owner") #the name 'objects' is the Manager
rangers = {}
for e in salespersons:
k = salespersons.get(id = e.id)
v = k.solarclients.all()
rangers[k] = v
return render(request, 'homeowners.html', {'homeowners': homeowners, 'salespersons': salespersons, 'rangers': rangers })
I then iterate over the dictionary using:
{% for key, values in rangers.items %}
... display salesperson
{% if values %}
{% for v in values %}
.... display clients
{% endfor %}
{% else %}
... display "No Clients"
{% endif %}
{% endfor %}
Is there a more efficient way to do this? It seems silly to put the data into a dictionary to display it, but after many, many hours of trying different methods, this is the only way I could display the data.
thanks for any suggestions.
views.py
class Homeowners(DetailView):
def get(self, request, **kwargs):
salespersons = WhoAmI.objects.all()
return render(request, 'homeowners.html', {'salespersons': salespersons })
html:
{% for sales in salespersons %}
{% for client in sales.solarclients.all %}
------ Print Client
{% empty %}
---- Client not exist
{% endfor %}
{% endfor %}
There is a nice handy template filter called regroup built in Django which does exactly what you're looking for.
# views.py
homeowners = SolarClient.objects.all().order_by("client_owner").select_related('client_owner')
return render(request, 'homeowners.html', {'homeowners': homeowners})
# homeowners.html
{% regroup homeowners by client_owner as home_owners_list %}
<ul>
{% for client_owner in home_owners_list %}
<b>{{ client_owner.grouper }}</b>
<ul>
{% for client in client_owner.list %}
<li>{{ client.name }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
The select_related method is just for performance improvement and omitting it wouldn't affect functionality.
In the template:
<h4>
{% if data.wine_one %}
{{ data.wine_one.title }}
{% elif data.news_one %}
{{ data.news_one.title }}
{% endif %}
</h4>
I promise the data.wine_one is exists, because in the views.py I have print out it.
But in the templates it do not shows up the data.wine_one.title, and I use the data.wine_one != None can not judge it too.
EDIT
In the views.py:
def getData():
banner = models.Banner.objects.filter(fk_info=1)
info = models.Info.objects.all().first()
aboutus = models.AboutUs.objects.all().first()
winery = models.Winery.objects.all()[:3]
winery_consult = models.WineryConsult.objects.all()[:4]
data = {
'banner': banner,
'info': info,
'aboutus': aboutus,
'winery': winery,
'winery_consult': winery_consult,
}
return data
def productdetails(request, nid):
data = getData()
wine_one = models.Winery.objects.filter(id=nid).first()
data['wine_one'] = wine_one
print (data['wine_one'].title) # there ouput the "gaoliangjiu"
return render(request, 'article_list_content.html', data)
You've misunderstood how the template context works.
There's no element called data in the template; that's just the local variable you're using in the view to build up the context. In the template, you just reference the keys of that object directly. So it should be:
{% if wine_one %}
{{ wine_one.title }}
{% elif news_one %}
{{ news_one.title }}
{% endif %}
views.py
def what(request):
user = request.user
report = Report.objects.get(user=user.id)
reportnotesform=ReportNotes(instance=report)
reportform = ReportForm(instance=report)
typeList = Types.objects.filter(user=user, is_active=True,parent_type_id=None)
list = []
for type in typeList:
if not type.parent_type_id:
list.append(type)
subtype = Types.objects.filter(parent_type_id=type.id, is_active=True)
for subtypes in subtype:
list.append(subtypes)
if request.method == 'POST':
ReportType.objects.filter(report=report).delete()
checked_ones = [unicode(x) for x in subtype if unicode(x) in request.POST.keys()]
reportnotesform=ReportNotes(request.POST,instance=report)
if reportnotesform.is_valid():
report=reportnotesform.save(commit=False)
report.user=request.user
report.save()
for entry in checked_ones:
r = ReportType()
r.report = report
r.title = entry
r.save()
return redirect('/member/where/')
checked_ones = [x.title for x in ReportType.objects.filter(report=report)]
return render(request, 'incident/what.html',
{
'newreport_menu': True,
'typeList':list,
'checked_ones':checked_ones,
# 'typelist': typelist,
'ReportNotes':reportnotesform,
'ReportForm':reportform
})
models.py
class ReportType(models.Model):
report = models.ForeignKey(Report)
title = models.CharField('Incident Type', max_length=200)
template
{% for type in typeList%}
{% if type.parent_type_id == None %}
<h1>{{type.title}}</h1>
{% else %}
<p><input type="checkbox">{{type.title}}</input></p>
{% endif %}
{% endfor %}
I am using model form to display the check box,dynamically.
This is my view where i am taking the values from database and displaying.The values filtered by typelist object requires to display values along with check box.For types object,doesn't matter.Is any way to do it in django.
This should work for you:
<h1> {% for type in types %}{{type.title}}<br />{% endfor %}</h1>
<form action="" method="post">
{% for field in typelist %}
{% if field.title in checked_ones %}
<label><input type="checkbox" checked="true" name="{{field}}">{{ field }}</label><br />
{% else %}
<label><input type="checkbox" name="{{field}}">{{ field }}</label><br />
{%endif%}
{% endfor %}
</form>
def what(request):
user = request.user
types = Types.objects.filter(user=user.id, parent_type_id=None).order_by('title')
typelist=Types.objects.filter(user=user.id,parent_type_id__isnull=False).order_by('title')
reporttypeForm = ReportTypeForm()
if request.method == 'POST':
ReportType.objects.filter(report=#your report).delete()
checked_ones = [unicode(x) for x in typelists if unicode(x) in request.POST.keys()]
for entry in checked_ones:
r = ReportType()
r.report = # the hardcoded report
r.title = entry
r.save()
...
reporttypeForm = ReportTypeForm(request.POST)
if reporttypeForm.is_valid():
reporttypeForm.save()
checked_ones = [x.title for x in ReportType.objects.filter(report=#your report)]
return render(request, 'incident/what.html',
{
'checked_ones':checked_ones,
'newreport_menu': True,
'types':types,
'typelist': typelist,
'reporttypeForm':ReportTypeForm
})
Good luck!
Without knowing anything about why you're trying to do it this way, it looks like you're overcomplicating your problem by trying to make it dynamic, when you could just use a models.BooleanField(), which Django will automatically display as a checkbox. It'd be simpler, and make the code easier to read too.