How to check existence of an object using pk in django template? - python

I tried this if condition to show previous and next posts only if it exists in database.
{% if blog.pk|add:-1 %}
Previous Post
{% endif %}
{% if blog.pk|add:1 %}
Next Post
{% endif %}
but, it kinda ignores the condition and always show next and previous posts buttons owing to the fact that this condition is wrong. How do I fix this?

Please, don't implement this in the template. Templates should be used for rendering logic, not business logic.
You can define a method for example on your Post object to obtain the previous and next item:
class Blog(models.Model):
# …
def get_next(self):
return Blog.objects.filter(pk__gt=self.pk).order_by('pk').first()
def get_previous(self):
return Blog.objects.filter(pk__lt=self.pk).order_by('-pk').first()
Then you thus can use these methods:
{% with prev_blog=blog.get_previous %}
{% if prev_blog %}
Previous Post
{% endif %}
{% endwith %}
{% with next_blog=blog.get_next %}
{% if next_blog %}
Next Post
{% endif %}
{% endwith %}
This will also fetch Blog objects if there is a "gap". So if there is no Blog object with pk=4, then the get_previous of a Blog with pk=5, will be a Blog with pk=3.

Related

How to get out of nested for? In Django Template

I have a nested loop to display content and apply terms in my template.
{% for class in class %}
{% if saveclass %}
{% for saveclass in saveclass %}
{% if class.colecl in saveclass.saveclass_tag %}
save class exists!
{{ class.levelclass_name }}<br>
{% else %}
save class not exists!
{{ class.levelclass_name }}<br>
{% endif %}
{% endfor %}
{% else %}
there is nothing save class
{{ class.levelclass_name }}<br>
{% endif %}
{% endfor %}
The first loop gives me the list of classes.
Then it is checked whether the saveclass variable exists or not, if there is, the second loop is executed.
In the second loop it gives me saveclass and I check if the class tag is in the saveclass table and I display the output.
The problem is that the inner circle has to end to get to the next class. And for this reason, both the first if and its else are executed.
Python and other languages use breaks for this, but Django does not have a break template.
What is your solution?
Thank
I researched and according to friends Django template did not allow the break of the ring and should be managed in views.

How do i specify a variable in side of django template file

So I am trying to declare a variable inside of my django templates file
{% with object = "{{object.id
}}" %}
{% for detail in details %}
{% if detail.post.id == {{object}} %}
{{detail.name}}
{% endif %}
{% endfor %}
{% endwith %}
I know that with is used to this job, but when i run this code it shows me this error: 'with' expected at least one variable assignment
Please help me. Thank You
The post_id is likely an int so you should specify object as {% with object=2 %}, you furthermore should not use double curly brackets in a template tag:
{% with object=2 %}
{% for detail in details %}
{% if detail.post_id == object %}
{{ detail.name }}
{% endif %}
{% endfor %}
{% endwith %}
It is however not a good idea to filter in the template, since this is not efficient, and requires more memory, normally you filter in the view.

Django Endless Pagination - Multiple paginations in the same page

My Django version is 1.10.5
With Django Endless Pagination 3.0.1 i want to show two or more paginated lists(see code) on my site.
For that i try to do this tutorial but the solution raises everytime an error if i use a second variable or multiple variables. The second variable(the querystring) in the tutorial is "other_entries_page".
The answer from the testserver: Invalid arguments for u'paginate' tag
I have no idea whats going wrong.
Here is the code from the tutorial:
{% load el_pagination_tags %}
{% paginate entries %}
{% for entry in entries %}
{# your code to show the entry #}
{% endfor %}
{% show_pages %}
{# "other_entries_page" is the new querystring key #}
{% paginate other_entries using "other_entries_page" %}
{% for entry in other_entries %}
{# your code to show the entry #}
{% endfor %}
{% show_pages %}
The variables that i mean are GET-variables(like: http://example.com/?page=2).
I hope you can help me.

how to get a list of questions posted by followed users

Friends, I am trying to implement a question answer site in which a logged in user gets a list of questions and answers asked by the users he follows.
I am using django-friendship to implement user follows. I want to know how we can fetch all the questions posted by the users whom the current user follows.
I have tried the following but doesn't work.
views.py
def index(request):
if request.session.get('current_user'):
questions = []
users = Follow.objects.following(request.user)
i = 0
while i < len(users):
posts = Question.objects.filter(user=users[i])
questions.append(posts)
i = i + 1
return render(request, "welcome/index.html",locals())
Here's my template
welcome/index.html
{% extends "layout.html" %}
{% block content %}
{% for q in questions %}
{{ q.title }}
{% endfor %}
{% endblock %}
You can fetch all questions without looping
views.py
def index(request):
if request.session.get('current_user'):
users = Follow.objects.following(request.user)
questions = Question.objects.filter(user__in=users)
return render(request, "welcome/index.html",locals())
template
{% extends "layout.html" %}
{% block content %}
{% for q in questions %}
{{ q.title }}
{% endfor %}
{% endblock %}
posts is a queryset. Thus, questions is a list of querysets and, in your template, you are not iterating over Question instances, but querysets that do NOT have a title attribute. You can try in your view:
questions.extend(posts) # not: append
in order to obtain an actual list of Question instances. Or, you can change your template:
{% for qs in questions %}
{% for q in qs %}
{{ q.title }}
{% endfor %}
{% endfor %}

Conditionally extending a template in Django

I have a download page on a Django site that I want to serve for both users who are logged in and who aren't. Instead of having a user_download.html and login_download.html, I want to have a single download.html that conditionally extends the correct base.
However, I get an error when I use the following code.
{% if user.is_authenticated %}
{% extends 'user_base.html' %}
{% else %}
{% extends 'login_base.html' %}
{% endif %}
{% block content %}
<h2>Downloadable content</h2>
...
{% endblock %}
The error I receive is
TemplateSyntaxError at /download/
Invalid block tag: 'else'
What's wrong with the else? I tried
{% if user.is_authenticated %}
{% extends 'user_base.html' %}
{% else %}{% if AnonymousUser.is_authenticated %}
{% extends 'login_base.html' %}
{% endif %}{% endif %}
{% block content %}
<h2>Downloadable content</h2>
...
{% endblock %}
but this didn't work, either.
Thanks,
erip
The {% extends %} tag supports variables. See the doc for reference.
def my_view(request):
if request.user.is_authenicated
base_template_name = 'user_base.html'
else:
base_template_name = 'login_base.html'
# Pass base template name to the renderer
return render_to_response('your_template.html', {'base_template_name':base_template_name})
Template (please note that the value is not quoted):
{% extends base_template_name %}
...
You're getting an error because extends needs to be defined at the top of the template. extends controls template inheritance: you are basically creating a subclass from some parent class, which is why extends needs to be the first thing in the template.
Imagine writing a class, and in the __init__() you said something like
class DoesntKnowWhereToInheritFrom(object):
def __init__():
if something:
self.inherits_from(x)
else
self.inherits_from(y)
The compiler/interpreter would freak out.
The common way to do what you are trying to do here is to check for is_authenticated in the view, and then render the appropriate template.

Categories