Django consulta muchos a muchos campos en la plantilla

¿Cómo puedo consultar un campo de muchos a muchos en una plantilla de Django?

Por ejemplo, esta declaración if no funciona (sé que no puedo llamar a funciones con argumentos en las plantillas de Django), pero esto muestra lo que me gustaría hacer:

plantilla.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 %}

modelos.py

class User(Model):
    # fields

class Post(Model):
    likes = ManyToManyField(User)

preguntado el 04 de julio de 12 a las 01:07

El sistema de plantillas de django estándar no permite llamar a métodos con parámetros. Puede usar Jinja2 si desea llamar al código anterior. -

2 Respuestas

Para hacer lo que buscas, podrías hacer lo siguiente:

{% 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 %}

Alternativamente, podría usar el enfoque de Greg. La ventaja de su respuesta es que escalaría mejor cuando ingrese a conjuntos de datos muy grandes. Este enfoque no requiere que escriba ningún filtro personalizado.

Respondido 04 Jul 12, 08:07

No funciona porque parece estar escribiendo código python en una plantilla... debe ejecutar el ciclo en su vista y pasar una lista de publicaciones y su información a la plantilla, o escribir un filtro de plantilla que determine si a un determinado usuario le gusta una publicación. Por ejemplo:

from django import template

register = template.Library()

@register.filter
def is_liked_by(post, user):
    return bool(post.likes.filter(user=user))

Luego en tu plantilla:

{% 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 %}

Respondido 04 Jul 12, 02:07

Es posible que desee considerar usar .exists() en lugar de bool(post.likes.filter(user=user)) en el conjunto de consultas. Es marginalmente más rápido y este parece ser el caso para el que fue diseñado. Se usaría así: return post.likes.filter(user=user).exists() - casi flan

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.