How to pass parameter from view to template in django? - django

I want to pass value of variable from django view to template.
view:
def countsnippet(request):
checkins = Attendee.objects.filter(checkin=True).count()
return render( request, 'search/countsnippet.html', {'inft': checkins} )
Template snippet:
<div class="row" >
{% block content %}
<p>INFT : {% 'inft' %}</p>
{% endblock %}
</div>
I want to pass checkins value to template, but using above approach is giving me error.

You render a "variable" by placing it between double curly brackets ({{ }}), like:
<div class="row" >
{% block content %}
<p>INFT : {{ inft }}</p>
{% endblock %}
</div>
The variable name is not surrounded by quotes, and you can treat it thus like an identifier.
You can furthermore use a sequence of identifiers separated by dots (like {{ foo.bar }}) to access the bar attribute/element of foo.
Furthermore Django templates allow extra features like template filters, etc. See the Django documentation on the template language for an in-depth article.

Related

django template, using {% with %} to set a list var

I need to hard set a list in django template.
I know that I have to pass variables to the template, instead of creating them in the template, but I only have access to the template file. I'm using sendinblue with a custom template, and the only way to use custom params injected to the template is to use their api. I only need to hardcode some content in a list, and the content will dynamically appear depending on contact, I think that using an api only for this is overkill.
{% with tt='123'|make_list %}
{{ tt }}
<hr>
{% for x in tt %}
{{ x }}<br>
{% endfor %}
{% endwith %}
try this

Custom Template Tag Queryset Not Returning Anything

I'm trying to implement a feature that displays the 5 most recently created events. I decided to implement this with Django custom template tags (if this is not the best way, let me know). What I have so far is:
In event_search.html (among other things):
{% extends 'base.html' %}
{% load eventSearch_extras %}
<p>count: {{ recents.count }}</p>
<ul>
{% for e in recents %}
<li> {{e.title}} </li>
{% empty %}
<li> No recent events </li>
{% endfor %}
</ul>
In eventSearch_extra.py:
from django import template
from eventSearch.models import Event
register = template.Library()
#register.inclusion_tag('eventSearch/event_search.html')
def mostrecentevents():
"""Returns most 5 most recent events"""
recents = Event.objects.order_by('-created_time')[:5]
return {'recents': recents}
My issue here is that the queryset 'recents' appears to return empty to the template. 'count:' shows nothing & the for-loop defaults to 'No recent events'.
You've loaded the inclusion tag function, but not the individual tag, so the code to populate that information is never called; it's also laid out slightly oddly, so you're calling from the wrong place.
The main template calls the inclusion tag by using:
{% load eventSearch_extras %}
And you include the actual tag by calling
{{mostrecentevents}}
mostrecentevents goes off and runs the code, parses the html of event_search.html and puts it in the main template. The way your code is set out just now, you'd be calling an inclusion tag from its own HTML.
Main template > {% load inclusion_tags %} {{ actual_tag }}
As an example, I have a restaurant template. In that template is this code:
{% load restaurant_menu %} <!--main inclusion tag .py file) -->
{% menu %} <!-- the actual tag code you want to run -->
in restaurant_menu.py I have the following (additional irrelevant stuff removed):
#register.inclusion_tag('core/_menu.html', takes_context=True)
def menu(context):
filtered = context['filtered']
from core.models import MenuItem, FoodProfile, Ingredient, Recipe
if filtered:
restaurant = context['restaurant'].id
filtered_menu = #stuff here
restaurant_menu = filtered_menu
else:
restaurant_menu = MenuItem.objects.filter(restaurant__pk=context['restaurant'].id)
return {"restaurant_menu": restaurant_menu,
"number_of_menu_items": restaurant_menu.count(),
"filtered": filtered}
and the _menu.html page (underscored so I know it's a fragment) :
<ul>
{% for item in course.list %}
<li>
{{ item.number|floatformat:0 }} {{ item.name }} {{ item.description }} {{ item.price }} </li>
</li>{% endfor %}
{% endfor %}
</ul>
An inclusion tag is used to render another template. It doesn't make sense to create an inclusion tag that renders event_search.html, then call that template tag inside event_search.html itself. Note that you haven't actually used the template tag (with {% mostrecentevents %}), all you have done is load the template tag library.
It would be easier to use a simple tag instead.
#register.simple_tag
def mostrecentevents():
"""Returns most 5 most recent events"""
recents = Event.objects.order_by('-created_time')[:5]
return recents
Then in your template you can do:
{% load eventSearch_extras %}
{% mostrecentevents as recents %}
This loads the result of the template tag into the variable recents, and you can now do:
<p>count: {{ recents.count }}</p>
<ul>
{% for e in recents %}
<li> {{e.title}} </li>
{% empty %}
<li> No recent events </li>
{% endfor %}
</ul>
Note you can only use the as recents syntax with simple tags with Django 1.9+. For earlier versions, you can use an assignment tag instead.

Django "with" template tag renders empty for ForeignKey relationship

I was using the count method on a queryset context variable more than once in a template, so I decided to store it in a reusable variable:
{% with album.photograph_set.count as numPhotos %}
<title>My title with {{ numPhotos }} in it</title>
<span>I use {{ numPhotos }} here, too</span>
{% endwith %}
The numPhotos variable always seems to be blank, though replacing it with album.photograph_set.count inline still returns the appropriate value. I also tried using the {% with numPhotos=album.photograph_set.count %} syntax but it exhibits the same behavior. I use the {% with ... as ... %} syntax elsewhere in my code and it works as expected.
Any help is appreciated.
If photograph_set is the reverse relationship of a ForeignKeyField or if it's a ManyToManyField, you'll need to do
{% with album.photograph_set.all.count as numPhotos %}

Django template if statement always evaluates to true

This seems like it should be pretty straightforward, but for some reason I am unable to solve this problem. I'm using Django 1.4. I am trying to do a basic check to see if a list QuerySet is empty or not during template rendering, but the if statement I'm using seems always to evaluate to true.
I have a Django template that reads:
{% extends 'includes/base.html' %}
{% if object_list %}
...
{% block data %}
{% for object in object_list %}
...
{{ object.create_date }}
...
{% endfor %}
{% endblock data %}
...
{% endif %}
'base.html' has the block:
<body>
{% block content %}
...
<div class="row-fluid">
<div class="span12">
{% block data %}
<div align="center"><i>No data.</i></div>
{% endblock data %}
</div><!-- span12 -->
</div><!-- row -->
{% endblock content %}
...
</body>
The view function generating the QuerySet is here:
def barcode_track(request, model):
query = request.GET.get('barcode_search', '')
object_list = model.objects.all()
if query:
object_list = model.objects.filter(barcode__icontains=query)
return render_to_response('barcode_track/barcode_list.html',
{'object_list': object_list, 'query': query},
context_instance=RequestContext(request))
Which is called via this form:
<form id="barcode_search_form" method="get" action="" class="form">
<input type="text" name="barcode_search" value="{{ query }}" />
<button type="submit" class="btn">Search</button>
</form>
And the urls.py line:
urlpatterns = patterns('barcode_track.views',
url(r'^$', 'barcode_track', {'model': Barcode},
name="barcode_track"),)
The idea is that results will only be presented if they exist in object_list, and otherwise the parent block will remain unaltered. I have tried changing the name of object_list, and I have printed {{ dicts }} to the page to ensure that object_list is, in fact, empty (which it is). I am not using a generic view, although I realize that the name suggests as much. I have actually had this trouble in a different app I wrote using similar logic, so I must be doing something systematically incorrectly.
What am I missing here?
You can't wrap control flow tags like if around a block. Your problem is that the child template's definition for block data is being used simply because it's there.
You can fix it by placing the if tag inside block data. If you want to inherit the parent's contents when the list is empty, add an else case that expands to {{ block.super }}.

Using django template tags with JavaScript

How can I use Django's template tags within JavaScript? This is my code:
{% block scripts %}
<script>
$(document).ready(function() {
var classEditor = {
dcg: $("div.control-group"),
set: function(i, errors) {
$dcg = $(classEditor.dcg[i]);
$dcg.addClass("error");
$dcg.children('div').children('div').children('p').text(errors);
}
};
{% if form.email.errors %}
{% for err in form.email.errors %}
{{ e|add:err }}
{% endfor %}
classEditor.set(1, {{ e }});
{% endif %}
})
</script>
{% endblock %}
I want to send all errors to a function and do something with it. I tried to use striptags and stringformat, but it always raises errors.
I don't think your problem has to anything to do with Javascript. The issue is here:
{{ e|add:err }}
This makes no sense at all. It seems like you're trying to build up a list, e, consisting of all the items in form.email.errors. But you can't do that sort of thing in a template - no data manipulation is allowed, by design. The add filter simply performs numeric calculations for display, it doesn't modify objects.
You probably want to serialize the errors to JSON in your view, and pass that JSON object to classEditor.set.