Django: Ejemplo de etiqueta de plantilla personalizada simple

Tengo usuarios , videos , temas , criterios y calificaciones

  • Un video tiene un tema
  • Un tema tiene criterias
  • Un usuario puede crear un video para un tema determinado
  • Un usuario puede calificar un video en cada criterio dado para el tema en cuestión.

Puede ver mi publicación original Django – Modelo de calificación Modelo DetailView Template para obtener detalles sobre el modelo utilizado

He extendido una plantilla DetailView basada en el modelo de video para poner la lista de clasificaciones del video seleccionado para un usuario dado como contexto adicional.

 class VideoFileDetailView(DetailView): model = VideoFile def get_context_data(self, **kwargs): context = super(VideoFileDetailView, self).get_context_data(**kwargs) context['rates'] = VideoRate.objects.filter(video=self.object, user=self.request.user) return context 

En la plantilla señalada por DetailView , me gustaría enumerar los criterios del video , y para cada criterio mostrar el valor de calificación actual del usuario .

 
    {% for crit in videofile.topic.crits.all %}
  • {% for rate in rates %} {% if rate.crit.id == crit.id %} {{ rate.rate }} {% endif %} {% endfor %}
    {{ crit }}
  • {% endfor %}

( rateit es un plugin jquery que uso para dibujar bonitos controles de calificación de estrellas)

De hecho, obtengo mis valores de calificación aquí en el 2do pero estoy seguro de que hay una mejor manera de hacerlo. De hecho, todavía no estoy seguro sobre la corrección de mi modelo .

Finalmente me gustaría reemplazar {# The rating value #} por el valor de rating de rate para el crit actual (en el loop). Cómo puedo hacer eso ?

Aquí está mi solución (basada en una etiqueta personalizada ):

Primero crea la estructura del archivo. Vaya al directorio de la aplicación donde se necesita la etiqueta y agregue estos archivos:

 templatetags templatetags/__init__.py templatetags/video_tags.py 

El archivo templatetags / video_tags.py :

 from django import template register = template.Library() @register.simple_tag def get_rate(crit, rates): return rates.get(crit=crit).rate 

La parte de la plantilla, con nuestra etiqueta de llamada:

 {% load video_tags %} 
    {% for crit in videofile.topic.crits.all %}
  • {{ crit }}
  • {% endfor %}

HTML en línea en la etiqueta

Si el HTML es pequeño, este método es más conveniente que crear un archivo separado.

Este ejemplo tiene en cuenta los enlaces a los perfiles de usuario. El archivo templatetags/somemodule.py contiene:

 from django import template from django.template import Template register = template.Library() @register.simple_tag(takes_context=True) def user_link(context): return Template('{{ user.username }}').render(context) 

Template#render ya devuelve una cadena segura que no es XSS escapada. Por ejemplo, si hubiéramos hecho solo:

 return '
'

se escaparía. También es posible que desee jugar con mark_safe .

Puede hacer que esa etiqueta esté disponible en todas las vistas con:

 TEMPLATES = [ { 'OPTIONS': { 'builtins': [ 'myprojectname.templatetags.somemodule', 

en settings.py

Ver también: