J'ai tilisateurs, vidéos, sujets, critères et évaluations
Vous pouvez voir mon message d'origine Django - Modèle de notation exemple DetailView Template pour obtenir des détails sur le modèle utilisé
J'ai étendu un modèle DetailView
basé sur le modèle video pour mettre la liste des ratings pour le video sélectionné pour une donnée tilisateur comme contexte supplémentaire.
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
Dans le modèle pointé par le DetailView
, je voudrais lister les critères des vidéo, et pour chaque critères afficher la valeur de notation actuelle sous la forme tilisateur.
<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 est un plugin jquery que j'utilise pour dessiner de jolis contrôles de notation d'étoiles)
En fait, je reçois mes valeurs de notation ici dans le 2ème for
mais je suis sûr qu'il existe une meilleure façon de le faire. En fait, je ne suis toujours pas sûr de mon modèle exactitude.
Enfin, je voudrais remplacer {# The rating value #}
par la valeur de notation du taux pour le critique actuel (dans la boucle). Comment puis je faire ça ?
Voici ma solution (basée sur un tag personnalisé):
Créez d'abord la structure du fichier. Allez dans le répertoire de l'application où la balise est nécessaire et ajoutez ces fichiers:
templatetags
templatetags/__init__.py
templatetags/video_tags.py
Le fichier 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 partie modèle, avec notre appel de tag:
{% 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>
HTML en ligne dans la balise
Si le code HTML est petit, cette méthode est plus pratique que la création d'un fichier séparé.
Cet exemple supprime les liens vers les profils utilisateur. Le fichier templatetags/somemodule.py
contient:
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
renvoie déjà une chaîne sûre qui n'est pas échappée XSS. Par exemple. si on avait fait juste:
return '<br>'
il serait échappé. Vous voudrez peut-être aussi jouer avec mark_safe
.
Vous pouvez rendre cette balise disponible sur toutes les vues avec:
TEMPLATES = [
{
'OPTIONS': {
'builtins': [
'myprojectname.templatetags.somemodule',
dans settings.py
.
Voir également: