I have users, videos, topics, criterias and ratings
You can see my original post Django - Rating Model Example DetailView Template to get details on the model used
I have extended a DetailView
template based on the video model to put the list of ratings for the selected video for a given user as extra context.
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
In the template pointed by the DetailView
, I'd like to list the criterias of the video, and for each criteria display the current rating value form the user.
<div id="rating"> <ul> {% for crit in videofile.topic.crits.all %} <li> {% for rate in rates %} {% if rate.crit.id == crit.id %} {{ rate.rate }} {% endif %} {% endfor %} <div class="rateit" data-rateit-value="{# The rating value #}" data-rateit-ispreset="true" crit-id="{{ crit.id }}"></div> {{ crit }} </li> {% endfor %} </ul> </div>
(rateit is a jquery plugin that I use to draw pretty stars rating controls)
Actually I get my rating values here within the 2nd for
but I'm sure there is a better way to do that. In fact, I'm still not sure about my model correctness.
Finally I'd like to replace {# The rating value #}
by the rating value from rate for the current crit (in the loop). How can I do that ?
Simple tags This function, which is a method of django. template. Library , takes a function that accepts any number of arguments, wraps it in a render function and the other necessary bits mentioned above and registers it with the template system.
To be a valid tag library, the module must contain a module-level variable named register that is a template. Library instance, in which all the tags and filters are registered. Show activity on this post. from django.
Here is my solution (based on a custom tag):
Firstly create the file structure. Go into the app directory where the tag is needed, and add these files:
templatetags templatetags/__init__.py templatetags/video_tags.py
The templatetags/video_tags.py file:
from django import template register = template.Library() @register.simple_tag def get_rate(crit, rates): return rates.get(crit=crit).rate
The template part, with our tag call:
{% load video_tags %} <div id="rating"> <ul> {% for crit in videofile.topic.crits.all %} <li> <div class="rateit" data-rateit-value="{% get_rate crit rates %}" data-rateit-ispreset="true" crit-id="{{ crit.id }}"></div> {{ crit }} </li> {% endfor %} </ul> </div>
Inline HTML in tag
If the HTML is small, this method is more convenient than creating a separate file.
This example factors out links to user profiles. The file templatetags/somemodule.py
contains:
from django import template from django.template import Template register = template.Library() @register.simple_tag(takes_context=True) def user_link(context): return Template('<a href="{% url \'user_detail\' ' + 'user.id %}">{{ user.username }}</a>').render(context)
Template#render
already returns a safe string which is not XSS escaped. E.g. if we had done just:
return '<br>'
it would be escaped. You might also want to play with mark_safe
.
You can make that tag available on all views with:
TEMPLATES = [ { 'OPTIONS': { 'builtins': [ 'myprojectname.templatetags.somemodule',
in settings.py
.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With