Django query manytomanyfield in template - python

How can I query a manytomanyfield in a Django template?
For example, this if statement doesn't work (I know I can't call functions with arguments in Django templates), but this shows what I'd like to do:
template.html
{% for post in posts %}
{% if post.likes.filter(user=user) %}
You like this post
{% else %}
<a>Click here to like this post</a>
{% endif %}
{% endfor %}
models.py
class User(Model):
# fields
class Post(Model):
likes = ManyToManyField(User)

In order to do what you are looking for, you could do the following:
{% for post in posts %}
{% if user in post.likes.distinct %}
You like this post
{% else %}
<a>Click here to like this post</a>
{% endif %}
{% endfor %}
Alternatively, you could use Greg's approach. The advantage of his answer is that it would scale better when you get into very large datasets. This approach does not require you to write any custom filters.

It doesn't work because you appear to be writing python code in a template... you need to either run the loop in your view and pass a list of posts and their information to the template, or write a template filter that determines whether a certain user likes a post. For example:
from django import template
register = template.Library()
#register.filter
def is_liked_by(post, user):
return bool(post.likes.filter(user=user))
Then in your template:
{% for post in posts %}
{% if post|is_liked_by:request.user %}
You like this post
{% else %}
<a>Click here to like this post</a>
{% endif %}
{% endfor %}

Related

Django get user data in main template

I'm trying to check if user logged in in the main template using this:
{%if request.user%}
...
{%endif%}
but it's not working maybe because main template doesn't have a view
could any one help i don't know if the question duplicated,but i didn't find my answer.
you could use:
{% if user.is_authenticated %}
...
{% endif %}
{% if user.is_authenticated %}
...
{% endif %}
Link to the Django docs. this should always be your first point of reference.

Django iterate queryset just n number of times in templates

My issue is quite simple. I am using Django taggit.
I want to iterate this only 2 times. Means to display only 4 tags in templates.
{% for tag in data.tags.all %}
{{tag}}
{% endfor %}
I have tried this, but it is not making any sense:
{% for tag in data.tags.all|ljust:"2" %}
{{tag}}
{% endfor %}
Can anyone suggest how can I achieve it?
You can make use of the |slice template filter [Django-doc]:
{% for tag in data.tags.all|slice:':2' %}
{{ tag }}
{% endfor %}

django concat string with comma in template

I am newbie in django. How can I concat string in a for loop in django template
{% for lead in project.leaders %}
{% if forloop.counter == 1 %}
{% lead_member = lead.0 %}
{% else %}
{% lead_member = ','.lead.0 %}
{% endif %}
{{ lead_member }}
{% endfor %}
Finally my lead_member should be test1,test2,test3....
what is happening now (my current code)
{% for lead in project.leaders %}
{{ lead.0}}
{% endfor %}
and the output is test1test2test3.... but i want to make same as test1,test2,test3....
Try this. it works
{% for lead in project.leaders %}
{{ lead.0 }}{% if not forloop.last %}, {% endif %}
{% endfor %}
There's no need to assign anything, nor do you need that type of complexity by using assignment tags. To keep your templating stupid-simple, you could always do this in your view, or even at the model level:
# don't step on the `join` built-in
from django.template.defaultfilters import join as join_filter
class Project(models.Model):
#property
def leaders(self):
return join_filter(self.objects.values_list('some_field', flat=True), ', ')
Then all you have to do in the template is:
{{ project.leaders }}
It's hard to understand your question, but I hope i did it. There is a number of related questions such as String-concatination,
How to concatenate in django
It's possible to create first string, concatinate it with comma and new string for every iteration. You are also able to make smth like ','.join(list_of_strings) on your server side before rendering. You can also join your list in templating by {{ list|join:", " }}.

How to use __repr__ method within django template?

For example, there is an object in a nested loop:
{% for fieldset in inline_admin_form %}
{% for line in fieldset %}
{% for field in line %}
{% if field.is_hidden %} {{ field.field }} {% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endif %}
Now I want to check the class name and some information about field.field, so I use field.field.__repr__() to replace field.field.
However, the django template complains about it after the change:
Variables and attributes may not begin with underscores: 'field.field.__repr__'
Does anyone have idea about this? And is there any better way to debug for a variable in django template? (I tried {% debug %} but found it awful when I want to check a variable in a nested loop..)
{{ value|stringformat:'r' }}
uses the string % operator style formatting with the r format which uses repr()
You could easily write a template filter which allows you to do {{ var|asrepr }}. See the documentation, but it'll look something like this:
#register.filter
def asrepr(value):
return repr(value)

Python template include a page if condition

i'm developing a small app with Python and Google app engine. I'm using boilerplate (https://github.com/coto/gae-boilerplate) as front-end which follows gae direction and python templates, so nothing diffrent than plain stuff.
Now, what i would like to have is this.
When a user logged in, if the field of name and last name are not filled in i would like to have, in the home page, the profile editing.
The page for editing the profile is a template (which extend the base.html), called edit_profile.html which works well.
The homepage is a template as well (extend the base.html) called home.html.
Now, can i include the edit_profile.html in home.html? how can i do it?
this is what i've, i don't know what to put instead of ???? i tried with
{% block edit_profile.html %} {% endblock %}
but does not work
{% if user_info.name and user_info.last_name %}
..
{% else %}
????
{% endif %}
thanks.
So you want to include only some block of given template. There are two solutions:
1) Create template just for profile editing form and include it into edit_profile.html. Then include it also into home.html to if condition branch:
profile_form.html:
<form action="{% url some-action %}">
{{ form }}
<input type="submit" value="save"/>
</form
profile_edit.html
{% extends "base.html" %}
{% block main %}
{% include "profile_form.html" %}
{% endblock %}
home.html
{% if user_info.name and user_info.last_name %}
{% include "profile_form.html" %}
{% endif %}
2) use variable for extended template:
profile_form.html
{% extend BASE_TEMPLATE %}
and set it into context w/ different value as needed:
in home.html (let's say included_form.html is some basic template)
{% if user_info.name and user_info.last_name %}
{% with "included_form.html" as BASE_TEMPLATE %}
{% include "edit_profile.html" %}
{% endwith %}
{% endif %}
and if you want show form as a standalone page, set BASE_TEMPLATE to base.html

Categories

Resources