so I have this html code:
<legend><h1 > Weapons that this character has </h1></legend>
<div>
<ul style="list-style-type:none" >
{% if request.GET.idChar %}
<li >{{ charname }} Has Maihand {{ mh }} and Offhand {{ oh }}</li>
{% else %}
<li>no</li>
{% endif %}
</ul>
</div>
The issue is that {{ charname }}, {{ mh }} and {{ oh }} are still displaying the brackets after i added flat=True in their line in views.py, in fact they stopped showing the parenthesys, but still showing the brackets. I also tried named=True, named=bool, flat=bool. Also tried values instead of values_list...
Views.py:
def character_weapons (request):
idchar = request.GET.get('idChar')
weapons = Characterweapons.objects.filter(characterid__exact=idchar).values_list('weaponid','categoryid_id')
charname = Characters.objects.filter(characterid__exact = idchar).values_list('name', flat=True)
print("charname: ")
print(charname)
if weapons[0][1] == 1:
mh_id = weapons[0][0]
oh_id = weapons[1][0]
elif weapons[0][1] == 2:
oh_id = weapons[0][0]
mh_id = weapons[1][0]
mh = Weapons.objects.filter(weaponid__exact=mh_id).values_list('weaponname', flat=True)
oh = Weapons.objects.filter(weaponid__exact=oh_id).values_list('weaponname', flat=True)
context={"mh": mh, "oh": oh,"idchar": idchar,"charname": charname}
return render(request,'users/character_weapons.html', context)
If someone knows how to fix it please let me know.
Thanks in advance!
values_list() with flat=True returns a list of values, so you have to extract the value with an index of 0 since your queries appear to always return only one row:
context={"mh": mh[0], "oh": oh[0],"idchar": idchar,"charname": charname[0]}
It's a flat list, but it's still a list. If you want to output it in one go, use the |join filter.
{{ mh|join:"," }}
Related
I need to do a counter increment within a loop. I had a look at django for.counter, but unfortunately, my increments dont exactly occur within each iteration of the loop. So is there any way at all that I can implement increment of a variable within django template, without going to great pains to implement a new object in my code to do this without such an increment?
In the following code, I am writing the lines {{ count = 0 }}, {{ count += 1 }} just for illustration purpose. I know it wont work. The following is a very simplified form of my template:
<div class="jumbotron slotgroup slotavailable mb-1 mt-5" id="jumbo_week_avail">
<div class="slot-header" role="alert">
Headertext
</div>
{% if weeklyslotsav %}
{% for day,daynum in weekzip %}
{{ count = 0 }}
{% if daynum in weeklyslotsav.day %}
{% for weekslotav in weeklyslotsav %}
{% if weekslotav.day == daynum %}
<div class="row row_week_avail{{ weekslotav.day }}" id="row_week_avail{{ weekslotav.day }}_{{ count }}">
</div>
{{ count += 1 }}
{% endif}
{% endfor %}
{% else %}
<div class="row row_week_avail{{ daynum }}" id="row_week_avail{{ daynum }}_0">
</div>
{% endif %}
{% endfor %}
{% else %}
{% for weekday, weeknum in weekzip %}
<div class="row row_week_avail{{ weeknum }}" id="row_week_avail{{ weeknum }}_0">
</div>
{% endfor %}
{% endif %}
</div>
The following is a segment from my views:
def edit_doctorslots(request, cliniclabel, doctor_id):
doctor_id=int(doctor_id)
doc = get_object_or_404(doctor, docid=doctor_id)
cl = Clinic.objects.get(label=cliniclabel)
print("Clinic name", cl.name)
regularslotsav = ''
try:
regularslotsav = Timeslots.objects.filter(clinic =cl, doctor =doc, available =True)
except:
pass
regularslotsbr = ''
try:
regularslotsbr = Timeslots.objects.filter(clinic =cl, doctor =doc, available =False)
except:
pass
weekavzip = ''
try:
weeklyslotsav = Weekdays.objects.filter(clinic =cl, doctor =doc, available =True)
weekav = range(0, len(weeklyslotsav))
weekavzip = list(zip(weeklyslotsav, weekav))
except:
pass
weeklyslotsbr = ''
try:
weeklyslotsbr = Weekdays.objects.filter(clinic =cl, doctor =doc, available =False)
except:
pass
formslot = SlotForm()
formspecialdays = SpecialdaysForm()
formweekdays = WeekdaysForm()
weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
weekdaynum = [0,1,2,3,4,5,6]
weekzip = list(zip(weekdays, weekdaynum))
newweekzip = weekzip
return render(request, 'clinic/editslots0.html', {'rnd_num': randomnumber(), 'clinic': cl, 'doctor': doc, 'formslot': formslot, 'formspecialdays': formspecialdays, 'formweekdays': formweekdays, 'weekzip': weekzip, 'newweekzip': newweekzip, 'regav': regularslotsav, 'regbr': regularslotsbr, 'weekav': weekavzip, 'weekbr': weeklyslotsbr, 'weeklyslotsav': weeklyslotsav })
I've seen many similiar questions on SO. However in all of them I've seen people introducing for.counter. But this is not suitable for my purpose.
You can use with tag to set variables in template as -
{% with count=0 %}
{{ count}}
...do other stuffs
{% endwith %}
and for maths you could use django math filters like
{{ count|add:"1" }}
You can code you with use of both.
For more about setting variable in django template - How to set a value of a variable inside a template code?
and for using math in django - How to do math in a Django template?
Hope this helps you.
Hi I have the following query in my views.py
m = Request.objects.filter(Q(type__icontains='4'), Q(wt__in =['giga','mega']))
context['all_items'] = m.values('type1').order_by('type1')
Its giving values sasoo, masoo, pisoo, kusoo etc.
How can I implement the Django Substr in this case so that my html will display values as sa, ma, pi, ku, ..
You can annotate the model
from django.db.models.functions import Substr
m = Request.objects.filter(Q(type__icontains='4'), Q(wt__in =['giga','mega']))
context['all_items'] = m.annotate(mysubstring=Substr('type1',1,2)).order_by('type1')
In template:
{% for obj in all_items %}
{# Use obj.mysubstring #}
{% endfor %}
You can use slice filter in your template:
{% for item in all_items %}
{{ item.type1|slice:":2" }}
{% endfor %}
One liner
context['all_items'] = [i[:2] for i in context['all_items']]
I have an InterField, that validates if a number is between the values 0 and 99. For some reason it never validates.
I have a feeling it is related to the FieldList and ther way I iterate over it in the template, but can't seem to get it working.
The form:
class dpiaImpactAnalysisForm(Form):
severity_score = IntegerField("Severity Score"),
validators=[NumberRange(min=0, max=99, message="Please provide a valid number")]))
identifiability_score = IntegerField("Identifiability Score"),
validators=[NumberRange(min=0, max=99, message="Please provide a valid number")]))
class dpiaThreatAnalysisForm(Form):
impact = FieldList(FormField(dpiaImpactAnalysisForm), min_entries=1)
In views I append the entries dynamically as required:
#app.route('/dpia/analysis/<project_id>', methods=["GET", "POST"])
def analysis(project_id):
form = dpiaThreatAnalysisForm()
prim = Assets.query.filter_by(selected=True, primary=True).all()
primary_assets = list(map(vars, prim))
ev = Events.query.all()
events = list(map(vars, ev))
# add fields to the form...
for z in range(len(prim) * len(ev)):
form.impact.append_entry()
supp = Assets.query.filter_by(selected=True, primary=False).all()
supporting_assets = list(map(vars, supp))
ths = Threats.query.all()
threats = list(map(vars, ths))
# add fields to the form
for z in range(len(ths) * len(supp)):
form.likelihood.append_entry()
if form.is_submitted():
print "submitted"
if form.validate():
print "valid"
print form.errors
if form.validate_on_submit():
# This is never printed:
app.logger.info("success!!")
pprint(form.likelihood)
return redirect(url_for(next_step, project_id=project_id))
return render_template('analysis.html', form=form, threats=threats, supporting_assets=supporting_assets, primary_assets=primary_assets, events=events)
In the template I iterate over a list primary_assets in a list events, and add the fields per iteration:
{% for val in events %}
{% if not counter or loop.index0 == 0 %}
{% set counter = [] %} <!-- loop hack !-->
{% endif %}
<strong>Event: {{ val.name }}</strong><br />
Jeopardizes: {{ val.jeopardizes }}<br />
{% for pa in primary_assets %}
<strong>{{ pa['name'] }}</strong><br />
{{ form.impact[counter|length].identifiability_score(placeholder='') }} <br />
{{ form.impact[counter|length].severity_score(placeholder='') }}
{{ form.impact[counter|length].hidden_tag() }}
{% if counter.append('1') %}{% endif %}
{% endfor %}
{% endfor %}
The hidden_tag() doesn't work either. Normally I iterate of the forms with with something like
{% for impact in form.impact %}
{{ impact.form.hidden_tag() }}
# do cbg
{% endfor %}
and that works, that's why I believe it's my manual looping that spoils it...
EDIT 2 march, 17:26
After some testing, I found that using
severity_score = IntegerField("Severity Score", validators=[Optional(), NumberRange(
min=0, max=9999999999, message="Please provide a valid number")])
works (if I set min=50 I get an error when inserting a number below 50), however, the CSRF is still not getting passed.
{{ form.impact[counter|length].hidden_tag() }} or
{{ form.impact[counter|length].form.hidden_tag() }} both don't work :(
I'm getting: {'impact': [{'csrf_token': ['CSRF token missing']}, {'csrf_token': ['CSRF token missing']}]}
EDIT 18:22
It seems that this: Form validation fails due missing CSRF is the solution. Investigating...
This: Form validation fails due missing CSRF is the solution.
In previous versions this wasn't needed, and after an installation of a new extension pip updated flask-wtf as well...
I pretty new to Django and I am trying to create an app to display tennis match results. So far, beyond my belief I have managed to hack together some code that is working.
However, I now have a problem though as currently I want to list the matches and their scores together in a template, but the number of sets can be different for each match and when I iterate through them I am getting an index error. Some matches may have 2 sets, others 3,4 or 5... perhaps some even just 1 if a player retires.
I have models for the match and each set, something like this. (I could get the match date, match, result and Set1 etc. for the player to display as those lists all have the same number of values. However, the length of list for set3 as an example is much shorter and causes an error.):
models.py
class Match(models.Model):
match_ID = models.AutoField(primary_key=True)
match_date = models.DateField()
players = models.ManyToManyField(Team, through='MatchStats', related_name='pim')
hometeam = models.ForeignKey(Team, to_field='teamname', related_name='hometeam')
awayteam = models.ForeignKey(Team, to_field='teamname', related_name='awayteam')
hometeam_sets = models.IntegerField()
awayteam_sets = models.IntegerField()
class Set(models.Model):
set_ID = models.AutoField(primary_key=True)
match = models.ForeignKey(Match)
set_number = models.IntegerField()
hometeam_games = models.IntegerField(default=0)
awayteam_games = models.IntegerField(default=0)
views.py
def playermatches(request, player_ID):
context = RequestContext(request)
p = get_object_or_404(Player, pk=player_ID)
match_list = Match.objects.filter(players=player_ID).order_by('-match_date')[:100]
i = len(match_list)
j = 0
#This works as all test matches have a 1st set!
s1_list = Set.objects.filter(match=match_list, set_number=1).order_by(-match__match_date')[:100]
"""
I am totally out of ideas as to what I might do next though.
Tried various things like 'if exists', 'try except IndexError etc'.
Below was the last thing I tried which failed yet again.
"""
s3_list = []
while j < i:
s3 = Set.objects.filter(match=match_list, set_number=3)[j]
if s3:
s3_list.append(s2)
else:
s3 = Set.objects.filter(set_ID=1)
s3_list.append(s3)
lst1 = match_list
lst2 = result_list
lst3 = s1_list
...
lst5 = s3_list
mandr = zip(lst1, lst2, lst3,... lst5)
context_dict = {...}
return render_to_response('stats/players.html', context_dict, context)
template.html
{% if matches %}
<ul>
{% for match, team, s1, s2 in mandr %}
<li>{{ match.match_date }} {{ match.hometeam }} vs. {{ match.awayteam }} ( {{ team.result }} )</li>
<li>{{ match.hometeam_sets }}:{{ match.awayteam_sets }} -- {{ s1.hometeam_games }}-{{ s1.awayteam_games }} {{ s3.hometeam_games }}-{{ s3.awayteam_games }}</li>
{% endfor %}
</ul>
{% else %}
<br/>
<strong>There are currently no matches in the system - try again tomorrow!</strong>
{% endif %}
Didn't need anything too fancy in the end. Realized that I need to lookup the related sets via the foreign key for each match... and then simply iterate over those in the template.
{% for match in mandr %}
{% for set in match.sets.all %}
{{ set.hometeam_games }}:{{ set.awayteam_games }}
{% endfor %}
{% endfor %}
Don't mix match list, result list with remaining lists. Pass them as separate objects in views and iterate over them in templates.
Change your views & template as follows.
views.py
m_list = match_list
r_list = result_list
list1 = s1_list
list2 = s2_list
..............
list5 = s3_list
mandr = zip(m_list, r_list)
my_lists = zip(list1, list2, ..., lst5)
templates.py
{% if matches %}
<ul>
{% for match, team in mandr %}
<li>{{ match.match_date }} <a href="/stats/match/{{ match.match_ID }}/">
{{ match.hometeam }} vs. {{ match.awayteam }}</a> ( {{ team.result }} )</li>
<li>{{ match.hometeam_sets }}:{{ match.awayteam_sets }} --
{% for lst in my_lists %}
<li>{{ lst.hometeam_games }}</li>
{% endfor %}
{% endfor %}
</ul>
{% else %}
<br/>
<strong>There are currently no matches in the system - try again tomorrow!</strong>
{% endif %}
if(len(f1) > 0):
for qs in profile_map:
p = Profile.objects.get(pk=qs.emp.id)
t_name = p.first_name + p.last_name
t_arr.append((q.profile.id,emp_name))
response_dictionary.update({'tarr':t_arr})
render_to_response('project/profile_table.html',context_instance=RequestContext(request,{'response_dictionary': response_dictionary}))
In Django template How to deocode all the 1.values of the tuple 2.search the tuple for a certain value in q.profile.id
{% for ele in response_dictionary.tarr%}
alert('{{ele}}');
//Get this as alert (11L, u'Employee3.')
{% endfor %}
In your case, the generator will assign the tuple to ele, so you can access the first, last name with {{ ele.0 }} {{ ele.1 }}.
But this is also legal, to unpack the tuple into two vars:
{% for first_name, last_name in response_dictionary.tarr %}
if you are using django 0.96 you can't have multiple values in for loop. so this will not work:
{% for first_name, last_name in response_dictionary.tarr %}
instead use
{% for ele in response_dictionary.tarr %}
{{ ele.0 }} {{ ele.1 }}
{% endfor %}