Django Template Tag Conditional - django

How make a a conditional statement out of a Django Template Tag?
from django import template
from django.contrib.auth.models import User, Group
register = template.Library()
#register.simple_tag
def is_designer(user_id):
try:
group = Group.objects.get(
name = "Designer",
user = user_id
)
return True
except Group.DoesNotExist:
return False
This appears True or False in my template which is correct:
{% is_designer user.id %}
However these gives me an error "Unused 'user.id' at end of if expression.":
{% if is_designer user.id == True %} Yes {% endif %}
{% if is_designer user.id %} Yes {% endif %}

If you made that into an assignment tag, you could do something like
{% is_designer user.id as is_user_designer %}
{% if is_user_designer == True %} Yes {% endif %}
{% if is_user_designer %} Yes {% endif %}
Note: As of Django 1.9, assignment tags are deprecated and simple tags can store values now. See the deprecation notice in the 1.9 docs https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/#assignment-tags

How about this one:
{% is_designer user.id as is_user_designer %}
{{ is_user_designer|yesno:"Yes," }}

Related

How to Use Custom Template Tag in Combination With Django's Built-in "with" Tag?

I have this simple tag:
myapp/templatetags/my_filters.py
#register.simple_tag
def get_bookmark_object(content_type, object_id):
return Bookmark.objects.get(content_type=content_type, object_id=object_id)
In my template, I want to be able to do this:
{% load my_filters %}
{% with object as bookmark %}
{% with bookmark_object=get_bookmark_object bookmark.content_type bookmark.object_id %}
{% if bookmark.content_type.model == 'post' %}
{% include 'content/post/object.html' with object=bookmark_object user_bookmark=bookmark %}
{% elif bookmark.content_type.model == 'note' %}
{% include 'content/note/object.html' with object=bookmark_object user_bookmark=bookmark %}
{% endif %}
{% endwith %}
{% endwith %}
I get the error:
TemplateSyntaxError at /my-page/
'with' received an invalid token: 'bookmark.content_type'
My question is:
How do I use my custom get_bookmark_object template tag in a with statement? An example with code would help me clarify a lot.
Reference:
Django's with built-in
What you defined is a template tag, you can assign the value produced by the template tag with an {% … as … %} tag:
{% get_bookmark_object bookmark.content_type bookmark.object_id as bookmark_object %}
…

Django simple tag doesn't work in if condition

I want to customize django-admin's change form for video objects by adding block with moderation tools.
When I use custom simpletags in if condition - it doesn't work.
models.py:
class Video(models.Model):
class Meta:
db_table = 'video'
DRAFT = 1
MODERATION = 2
PUBLISHED = 3
REJECTED = 4
HOSTING_UPLOADING = 5
SUSPICIOUS = 6
PUBLICATION_STATUSES = (
(DRAFT, 'draft'),
(MODERATION, 'moderation'),
(PUBLISHED, 'published'),
(HOSTING_UPLOADING, 'hosting uploading'),
(REJECTED, 'rejected'),
(SUSPICIOUS, 'suspicious')
)
video_pk = models.AutoField(primary_key=True)
name = models.CharField(max_length=150, blank=True)
hosting_id = models.CharField(max_length=20, blank=True)
publication_status = models.PositiveSmallIntegerField(choices=PUBLICATION_STATUSES, default=MODERATION)
templatetags video_publication_statuses.py:
from api.models import Video
from django import template
register = template.Library()
#register.simple_tag
def moderation(status):
return status == Video.MODERATION
#register.simple_tag
def suspicious(status):
return status == Video.SUSPICIOUS
#register.simple_tag
def published(status):
return status == Video.PUBLISHED
#register.simple_tag
def hosting_uploading(status):
return status == Video.HOSTING_UPLOADING
#register.simple_tag
def rejected(status):
return status == Video.REJECTED
change_form.html:
{% extends "admin/change_form.html" %}
{% load video_publication_statuses %}
{% suspicious original.publication_status as suspicious_status %}
{% moderation original.publication_status as moderation_status %}
{% hosting_uploading original.publication_status as hosting_uploading_status %}
{% published original.publication_status as published_status %}
{% rejected original.publication_status as rejected_status %}
{% block after_related_objects %}
{% if original.pk %}
{% for fieldset in adminform %}
{% if fieldset.name == 'Moderation' %}
{% include "admin/includes/fieldset.html" %}
{% endif %}
{% endfor %}
<div class="submit-row">
{% if rejected_status or moderation_status or suspicious_status %}
<input type="submit" value="Publish" name="publish" >
{% endif %}
{% if published_status %}
<input type="submit" value="Reject" name="reject" >
{% endif %}
</div>
{% endif %}
{% endblock %}
When I use explicit values instead of tags it works:
{% if original.publication_status == 3 %}
<input type="submit" value="Reject" name="reject" >
{% endif %}
Please help me understand what is wrong with tags?
I believe this is happening because template tags pass strings and you're checking a string against an integer e.g. return "3" == 3
Broadly speaking though, you're putting a lot of logic in a template and I typically avoid that situation. Template tags are reserved for "presentation logic" and I take that to mean "changing the way something is presented", not changing what is viewed. That logic belongs in a view or the model itself.
It should be easy enough to put this logic on your model.
class Original(...):
def rejected(self):
return self.status == Video.rejected

Could not parse the remainder django template

I have a condition within a loop in my template like this:
{% for message in message_trash %}
<td><a href="#">
{% if request.session.user_email == message.message_user_reciever.user_email %}
{{ message.message_user_reciever.user_firstName }} {{ message.message_user_reciever.user_lastName }}
{% elif request.session.user_email == message.message_user_sender.user_email %}
{{ message.message_user_sender.user_firstName }} {{ message.message_user_sender.user_lastName }}
{% endif %}
</a><small>Friends</small></td>
{% endfor %}
but i don't know why i get this error when applying the url?
TemplateSyntaxError: Could not parse the remainder: '==message.message_user_reciever.user_email' from 'request.session.user_email==message.message_user_reciever.user_email'
Update:
this is the view and variables that i render to the template:
def trashMessages(request, userId):
if isMessageOwner(request, userId):
user = Users.objects.get(user_id=userId)
message_trash = Messages.objects.filter(Q(message_user_reciever= user, message_sender_type='TRASH') | Q(message_user_sender=user, message_reciever_type='TRASH'))
return render(request, 'navigation_messages.html', {'user': user, 'message_trash': message_trash, 'type': 'trash'})
On testing your code out, I can only replicate your issue is by swapping:
{% if request.session.user_email == message.message_user_reciever.user_email %}
for
{% if request.session.user_email ==message.message_user_reciever.user_email %}
Note the missing space. Is the snippet in your question exactly as it is in your template?

for loop iteration in django

My coding is:
views
def showThread(request, thread_id)
post_list = Post.objects.filter(id = thread_id)
post_likes = PostLikes.objects.all()
return render_to_response('show.html',locals(),context_instance=RequestContext(request))
models:
class Post(models.Model):
subject = models.CharField(max_length = 250)
body = models.TextField()
thread = models.ForeignKey('self', null = True, editable = False )
Show.html:
{% for post in post_list %}
{{post.id}}{{post.subject}}
{% endfor %}
{% for post_like in post_likes %}
{% if post_like.post_id == post.id and post_like.user_id == user.id %}
U like this post{{post}}
{% else %}
{{post}}
{% endif %}
{% endfor %}
In the show.html, else part, it displays the values again and again. But i need only one time.How can i break the for loop when i enter into else condition.Please help me..
Django's for tag doesn't provide you with any means to break out of the loop. You'll simply have to filter the collection in your own view and slice it after the point your condition fails and supply that to your template.
You can use the django custom template tag found in this django snippets page. If you have doubts on using it, go to this page to learn about custom template tags.
Then load the template tag in your template using {% load loop_break %}. Then you can break the for loop as given below:
{% for post_like in post_likes %}
{% if post_like.post_id == post.id and post_like.user_id == user.id %}
U like this post{{post}}
{% else %}
{{post}}
{{ forloop|break }}
{% endif %}
{% endfor %}
Here the for loop will break when it enters the else part.
you could probably use ifchanged tag:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#ifchanged
However, you probably should consider moving this logic to view.
If you can structure your if statement to detect when you want to output nothing, you can simply put nothing inside your else clause:
{% for post_like in post_likes %}
{% if post_like.post_id == post.id and post_like.user_id == user.id %}
U like this post{{post}}
{% else %}
{% if forloop.first %}
{{post}}
{%else%}{%endif%}
{% endif %}
{% endfor %}
The above might not do quite what you want - you will have to tweak it yourself. The only thing you can't do is set a flag that this is the first entry into the else clause.

Accessing Many-to-Many Values Django

article = get_object_or_404(Article,slug=slug)
categories = article.category.all()
Using render_to_response() , how can I use the categories in the view ?
Assuming you have the article in the template, you can do the following:
# In your view
return render_to_response('page.html', {'article': article})
# In your template
{% for category in article.category.all %}
{{ category.attribute }}
{% endfor %}
# Or, if you already have the categories
return render_to_response('page.html', {'categories': categories})
{% for category in categories %}
{{ category.attribute }}
{% endfor %}