django template language - if statement issues - django

i am kind of new to django and i ran into a problem i couldnt find a solution to. In a template i render data from a custom context processor. There i use a for loop over all the queried items and a if statement, that checks that the data belongs to the person that is currently logged in:
{% for item in all_soli_accs %}
{% if item.owner == request.user.get_username %}
<a href="{% url 'url-soli-acc' item.soli_acc %} ">
{{ item.soli_acc }}
</a>
{% endif %}
{% endfor %}
Weirdly, the if statement doesnt return "true", when it is supposed to. The rendering doesnt output anything. In order to debug it, i tried to render {{item.owner}} and {{request.user.get_username}} and check if there are errors. But rendered as a variable, they return the same output, which lets me assume that it is all fine. I am confused. Does anyone has a solution to that? Do you need further information?
best regards

Use
request.user.username
Instead of
request.user.get_username

Related

Django template tag a model object.

I'm trying to return a different value for my model object rather than the information stored in the field.
I'm running this in my html file. I've passed a query of 'localcampaigns' to my html file.
In my HTML file I have:
{% for campaign in localcampaigns %}
{{campaign.title}}
{{campaign.time}}
{{campaign.event_date}}
{{campaign.project_focus}}
{% endfor %}
So specifically, say I run this and for the {{campaign.project_focus}} I receive the database object of 'community001' - I want to take this and return something different than this 'community001' like "Community Project"
I've tried to do this by:
{% if '{{campaign.project_focus}}' == 'community001' %}
Community Project
{% endif %}
But I'm unsuccessful. whenever I run != in the template tag, I get the response. So I know that the two don't match. How do I make the two match? Thanks.
{% if campaign.project_focus == 'community001' %}
Community Project
{% endif %}
campaign.project_focus without {{ }} because it's recognized inside the for loop

how can i accomplish the code below without custom vars in a Django template

{% for voter in opt.voterlog_set.all %}
{% if user.id != voter.voter.id %}
<span data-url="{% url vote %}" data-id="{{ opt.id }}" class="button">vote</span>
{% endif %}
{% endfor %}
In the code above I want to show the vote option once only if the current user hasn't already voted. The code above prints out the vote option multiple times (once for each entry in voterlog). Django doesn't let me set a custom variable such as a boolean which I can you use to toggle a hasVoted variable. How can I fix this code using Django templates?
Thanks for your help
Since, as you mention, there's no way to set state in a Django template, there isn't any sane way to do this if you don't have access to the view code. If you do have access to the view code, the easiest solution -- and, all in all, the most correct solution -- is to set a context variable user_has_voted in the view, instead of iterating through the voterlogs in the template.
But, if you don't have access to the view, you'll have to use a hack involving some client-side code, like rendering Javascript to set the necessary state and then adding some further Javascript to check that state and adjust the DOM after the page has loaded.
It seems like your logic is wrong though. You'd need something that sets state if and only if the current user IS found in the loop, like this:
{% for voter in opt.voterlog_set.all %}
{% if user.id == voter.voter.id %}
<script type="text/javascript">
window.user_has_voted = true;
</script>
{% endif %}
{% endfor %}
<script type="text/javascript">
if( !window.user_has_voted ) {
document.write('<span data-url="{% url vote %}" data-id="{{ opt.id }}" class="button">vote</span>');
}
</script>
Note that this is a particularly nasty hack -- it should only ever be used if you only have access to the templates and have no control over the context variables being sent in to the templates.
Probably this is not what you want, but what about creating the list of voters in your view, and add it to template context. Then
{% if user not in voters %}
"user is allowed to vote"
{% endif %}

Can I nest a "for" in an "if" in a Django template?

Just learning Django, and I'm trying to create a situation where when a template has layouts it'll list them, but if it doesn't it won't and will instead state that there are none.
I got an error message when I used only a "for layout..." statement on templates that had no layouts.
I figured things out to the point that I created an "if" statement to first check and see if the pages had layouts, and if not, an "else" statement to say that there are none.
The end result, though, is that the "for" seems to be completely ignored, and the "else" condition is applied on all pages -- whether or not they have associated layouts.
Code:
{% block header %}
<h1>The name of this template? It's {{ boilerplate.name }}.</h1>
{% endblock %}
{% block content %}
<p> </p>
<p>{{ boilerplate.content }}</p>
{% if layout in boilerplate.layouts %}
{% for layout in boilerplate.layouts.all %}
<p>{{ layout.user }} -- {{ layout.name }} ({{ layout.file.size }})
{% endfor %}
{% else %}
<p>There are no layouts for this template.</p>
{% endif %}
{% endblock %}
There's obviously something I'm missing. Possibly something very simple. What am I dong wrong?
Your {% if layout in boilerplate.layouts %} is what's wrong, but there's an easier way to achieve this than using an additional if tag.
As the documentation shows, you can use an optional empty tag to handle situations when you have no layouts. Rewriting your example code:
{% for layout in boilerplate.layouts.all %}
<p>{{ layout.user }} -- {{ layout.name }} ({{ layout.file.size }})
{% empty %}
<p>There are no layouts for this template.</p>
{% endfor %}
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for-empty
Look at this tag
To answer the subject of your question, yes, of course you can. My guess from the way you describe your problem is that there may be an issue with how you look for the layout in boilerplate.layouts.
boilerplate.layouts looks like it's a relational field. Thus, doing an in check on that alone may not be sufficient. In cases like this, I would recommend playing with this code in the shell, or in the view and seeing the result there, as it will greatly help debugging.
My simple guess is you need to do layout in boilerplate.layouts.all, but I am not familiar enough with your model, so wild guess :)

Calling a method on a model from a template

I am trying to call a method in a model from a template and I have come to the conclusion that this cannot be done.
This is my code
{% if request.user.is_authenticated %}
{% if a_story.is_story_liked(request.user.id) %}
<a class="story_like" data-id="{{ a_story.id }}" href="#">Like</a>
{% endif %}
{% else %}
<a class="story_like_login" data-id="{{ a_story.id }}" href="#">Like</a>
{% endif %}
The error happens on the second line. "is_story_liked" checks if the user has "liked" a story or not. If not, then I would write the same anchor tag but with a different class.
I am kinda stumped with this one. I am trying to output different class names: if the user is logged in, if the user is not logged in and if the user has "liked" or not "liked" an article/story.
Method calls in django templates work only if they don't have an argument (eg. {% if request.user.is_authenticated %}). You will either need to put that functionality in the view that renders this template or put this functionality in a custom template tag.

Display unescaped HTML String in Django Admin change list

I am currently facing a serious problem.
I use the standard django admin interface incl. change list to display one of my models.
The model has got a field, which includes a link (e.g. in database: http://localhost:8000/data/somefile.pdf'>link).
What I want now is that this string is rendered unescaped and displayed as link. I already tried the following in "change_list_results.html":
{% for result in results %}
<tr id="{{ result.1|adminfilter }}" class="{% cycle 'row1' 'row2' %}">
{% for item in result %}
{{ item|safe }}
{% endfor %}</tr>
{% endfor %}
I used "|safe" on the actual item that is output. Furthermore i tried "{% autoescape off %}". Same result, the String got escaped.
Do you see any other way to get the String displayed unescaped?
You want to set allow_tags=True on your method. It's a bit hidden, but it is described in the documentation - about a screen or so down from where this link takes you.