Django jinja if-elif statement breaks with == - django

So on my front-end, I want to show some HTML only if the user belongs to one of 2 groups: 'admins' or 'clerks'. There are 3 groups of users: 'admins', 'clerks', and 'sellers'. Here is my front-end code:
{% if user.groups.all.0 == "admins" %}
<h1>Some HTML</h1>
{% elif user.groups.all.0 == "clerks" %}
<h1>Some HTML</h1>
{% endif %}
When I run this code, the HTML shows for the admins. But that of the clerks does not show. I have tried printing out the group to be sure that the spelling and the casing were the same, and they were the same. And Django does not throw an error. It only works if I rewrite the code as follows:
{% if user.groups.all.0 == "admins" %}
<h1>Some HTML</h1>
{% elif user.groups.all.0 != "sellers" %}
<h1>Some HTML</h1>
{% endif %}
But I feel like this is not good design. Please am I missing something? Thank you all in advance

First of all, is a not practical idea for too many reasons.
Think that using that method you are getting possibilities and processing that don't correspond to the templates. The templates engine philosophy is just basic and no important logic.
A way to have more control and more practical is using a flag. For example
groups_permited_for_this=["admins","clerks",...]
Permited =False
for group in user.Groups.all:
if group.name in groups_permited_for_this:
Permited =True
Pass it as context and then use a Jinja if statement.

So I resolved the issue in a slightly different way from the one above:
First, I created a folder called 'templatetags' inside the app.
Then I created 2 files in it:
An empty 'init.py' file
A 'cust_auth.py'(for custom authentication) file
Inside the 'cust_auth.py' file I wrote a function that does a similar thing as in #Paulo Aguilar's answer above:
from django import template
from django.contrib.auth.models import Group
register = template.Library()
#register.filter(name='has_group')
def has_group(user, group_name):
group = Group.objects.get(name=group_name)
return True if group in user.groups.all() else False
Then in my template, I loaded the 'cust_auth.py' file at the top:
{% load auth_extras %}
Then I did the logic I was looking for:
{% if user|has_group:"admins" %}
<h1>Some HTML</h1>
{% endif %}
I preferred this because I think over the cause of my application, I will want more custom authentications
Thank you Paulo and whoever posts

Related

Reference Wagtail root page in templates

Currently I display a link to my sites homepage in the base template using this code :
{% if page.slug != 'homepage' %}
<!-- insert link code here -->
{% endif %}
However I like to reuse my code and sometimes the page is called something else. What I would like to write is something like :
{% if page != request.site.root_page %}
However this does not work, although if I display the values of these fields in the template they are both equal or not as expected ...
<p>{{ request.site.root_page }} and {{ page }}<p>
Results in :
<p>Contact and Contact</p> # On the root page
or
<p>Contact and Test</p> # On a different page
The opposite problem to this as the data is not specific to one page, but to every page except one.
What am I missing?
Okay in the process of explaining the question, I also found the answer. It doesn't work (I believe) because although these values look the same, they are actually objects with different properties, therefore the comparison fails.
In order for the comparison to succeed you need to extract values from each object and compare them. So this will not work ...
{% if page != request.site.root_page %}
However both of these do work ...
{% if page.title != request.site.root_page.title %}
... or ...
{% if page.url != request.site.root_page.url %}
Kicking myself now, but hopefully my public humiliation will help someone in the future.

Django templates - comparing variables to integer constants

Seems like elementary question, and yet can't get it work
{% if iterator.next > 10 %}
Do smth
{% endif %}
Two issues. First, this code just won't work (the code in the if-condition never implemented even when the condition seems to hold true), and second issue - the ">" sign is highlighted as if it where the closing tag of the closest open tag. Any ideas how to fix the first issue and is it all right with second issues ? Maybe there's some elegant syntax that I am missing and that would remove this ambiguity for the text editor ?
iterator.next may be a string which would result in the statement being False.
Try creating a custom filter to convert it to an int. For example create "my_filters.py":
# templatetags/my_filters.py
from django import template
register = template.Library()
#register.filter()
def to_int(value):
return int(value)
Then in your template:
{% load my_filters %}
{% if iterator.next|to_int > 10 %}
Do smth
{% endif %}
More on custom tags and filters here
I wouldn't worry about the highlighting, this may just be your IDE. I recommend using PyCharm for Django development
Django's docs says that you can use > with if tag:
{% if somevar < 100 %}
This appears if variable somevar is less than 100.
{% endif %}
take a look at documentation: https://docs.djangoproject.com/en/1.9/ref/templates/builtins/
maybe you are missing something else?

Django Pass Multiple Parameters to Custom Template Filter Inside If Statement

I have an issue. I've written a custom template tag with a function signature like this-
def has_paid_for_article(article, request):
Now, in my template tag I have a conditional statement to determine whether a user can download an article or not (this is determined by if the article is older than two years or the logged in user has paid for the article). Here's the snippet-
{% if article|is_older_than_two_years %}
<span class="amp">& </span>{% get_article_download_link article %}
{% else %}
download
{% endif %}
The aforementioned snippet works fine, however I need to call the has_paid_for_article() function inside of a conditional statement. I've tried the following ways to make this happen-
{% if article|is_older_than_two_years or article|request|has_paid_for_article %}
,
{% if article|is_older_than_two_years or [article, request]|has_paid_for_article %}
This one works outside of the conditional statement-
{% if article|is_older_than_two_years or has_paid_for_article article request %}
What would be the correct syntax here? Also, I've read other posts on the topic, I CANNOT put this logic in the view. I won't go into detail, but with the way it works, that is not an option. Thank you!
Try
{% if article|is_older_than_two_years or article|has_paid_for_article:request %}
See Writing custom template filters

django tags and html buttons

In my base.html I have:
blabla
{% ifequal alterprofile no %}
{% include 'registration/submittedprofile.html' %}
{% else %}
{% include 'registration/submittedprofile2.html' %}
{% endifnotequal %}
blabla
In views.py I have alterprofile = "no".
How do i change alterprofile to "yes". This is my submittedprofile:
<form action="" method="get">
blablabla
<input type="submit" value="Make Changes">
</form>
And this is my views.py:
def userprofile(request):
alterprofile = "no"
username = request.user
return render_to_response('registration/userprofile.html', {'user': username, 'alterprofile' = alterprofile})
Is there anyone who can code the answers for me. I've tried playing round with the previous answers but to no affect.
Django variables are rendered from the server side, so you can not change the variable after it was passed to your template. What you want to achieve is done via frontend scripting.
In this case you would pass both variables to the django template, save them in your Javascript and then switch them once you clicked the button you mentioned (via onClick event handling).
You can use url arguments like:
/myurl/
/myurl/?show2
then, in your views.py you can use request.POST['show2'] to check if exists and then send a variable again to the view to be checked with your {if}s
As an aside note, either you don't understand basic request flow with web applications or you are not explaining properly what you mean with "html button", so you are not fluent with html language. Sorry if my intuition is harsh or wrong.
its not that clear what you are asking but here is how to make the logic work as I think you want it based on yoru submitted code:
in your template change it to
ifequal alterprofile "no"
to include registration/submittedprofile.html.
When you change the view to alterprofile = "yes" the registration/submittedprofile2.html will be included instead if you keep your current template logic.
This is because in your view, alterprofile is assigned a string therefore its always a string. When you tried to test against no instead of "no" django was looking for a variable called no which doesn't exist.
This means that everytime you run it would have always included registration/submittedprofile2.html

Django Custom Inclusion Tags

I'm trying to build my own template tags.
I have no idea why I getting these errors. I'm following the Django doc's.
This is my app's file structure:
pollquiz/
__init__.py
show_pollquiz.html
showpollquiz.py
This is showpollquiz.py:
from django import template
from pollquiz.models import PollQuiz, Choice
register = template.Library()
#register.inclusion_tag('show_pollquiz.html')
def show_poll():
poll = Choice.objects.all()
return { 'poll' : poll }
html file:
<ul>
{% for poll in poll
<li>{{ poll.pollquiz }}</li>
{% endfor
</ul>
in my base.html file im am including like this
{% load showpollquiz %}
and
{% poll_quiz %}
Bu then I get the the error:
Exception Value: Caught an exception while rendering: show_pollquiz.html
I have no idea why this happens. Any ideas? Please keep in mind I'm still new at Django
Shouldn't all custom filters be inside the templatetags directory?
templatetags/
__init__.py
showpollquiz.py
then
#register.inclusion_tag('show_pollquiz.html')
looks in MY_TEMPLATE_DIR/show_pollquiz.html for the template
You forgot to close your template tags... Also, you should change the name in the for tag, you can't have for poll in poll:
<ul>
{% for p in poll %} <!--here-->
<li>{{ p.pollquiz }}</li>
{% endfor %} <!--and here-->
</ul>
Also notice you're not using the inclusion tag you defined at all. I think you got some code mixed up, try to go over a tutorial start to end and things will be clearer.
I'd not bother with writing your own template tags: take things one step at a time and stick to the basics for now. There's nothing wrong with {% include 'show_pollquiz.html' %}
I found the problem. The problem was that the #register.inclusion_tag('show_pollquiz.html')
inclusion tag is obviously looking for the template in the default_template directory. So that is why i got the error.
According to me this is not clear in the documentation. But I guess its how it is, being a template and all...
Oh , well.
Now, how would I put the #register.inclusion_tag('show_pollquiz.html') to look in the same folder as the app? under templatetags/?