2010-11-05 3 views
1

Bonjour je suis un Django débutant.Django comment rendre un tag de template personnalisé dans un inclusion_tag pour l'afficher dans la base.html

J'ai un calendrier que je veux afficher sur chaque site de ma page Web, donc j'appelle cela {% include "tags/my_calendar.html" %} dans mon base.html.

Comme je le sais jusqu'à présent, je peux afficher le calendrier en créant une balise de gabarit personnalisée ou en l'utilisant dans une vue Django standard. Je l'ai testé avec une vue Django standard, en appelant la fonction calendrier via un urls.py, cela fonctionne très bien. Mais je ne veux pas que le calendrier ne soit affiché que pour une URL spéciale. Puis-je le faire en définissant une balise de gabarit personnalisée?

J'ai essayé jusqu'à présent:

from django import template 
register = template.Library() 
@register.inclusion_tag("tags/my_calendar.html") 
def calendar(): 
""" 
Show calendar of events for specified month and year 
""" 
    lToday = datetime.now() 
    lYear = lToday.year 
    lMonth = lToday.month 
    my_workouts = ContestEvent.objects.filter(id__year=lYear, id__month=lMonth) 
    lCalendar = WorkoutCalendar(my_workouts).formatmonth(lYear, lMonth) 
    return {'calendar': mark_safe(lCalendar)} 

-je remplacer la classe HTMLCalender comme suit et tout cela fonctionne avec vue Django standard comme mentionné précédemment, mais le retour d'un render_to_response:

class WorkoutCalendar(HTMLCalendar): 

    def __init__(self, workouts): 
     super(WorkoutCalendar, self).__init__() 
     # self.workouts = self.group_by_day(workouts) 

    def formatday(self, day, weekday): 
     if day != 0: 
      cssclass = self.cssclasses[weekday] 
      if date.today() == date(self.year, self.month, day): 
       cssclass += ' today' 
      return self.day_cell(cssclass, day) 
     return self.day_cell('noday', ' ') 

    def formatmonth(self, year, month): 
     self.year, self.month = year, month 
     return super(WorkoutCalendar, self).formatmonth(year, month) 

    def day_cell(self, cssclass, body): 
     return '<td class="%s">%s</td>' % (cssclass, body) 

Mon \ tags \ mon_calendrier.html ressemble à ceci:

{% load calendar_tag %} 
<div> 
{% calendar %} 
</div 

Qu'est-ce que je fais e Sentiment mal? Je suis l'erreur suivante:

Request Method:  GET 
Request URL: http://127.0.0.1:8000/de/ 
Exception Type:  TemplateSyntaxError 
Exception Value:  

Caught an exception while rendering: maximum recursion depth exceeded 

Update1 Avec le soupçon de Daniel Roseman d'utiliser la syntaxe de variable {{ calendar }} au lieu de la syntaxe de la balise {% calendar %} je me suis débarrassé de l'erreur de récursivité, mais mon calendrier est toujours pas affiché. Je fais beaucoup d'enquêtes.

Quel est le problème ici?

Update2 après une enquête, j'ai trouvé ce court description utile sur la façon d'utiliser la balise modèle personnalisé. L'erreur pour laquelle le calendrier ne s'est pas affiché était que j'appelais {% include "tags/my_calendar.html" %} dans le fichier base.html, au lieu d'appeler la fonction de mon tag {% calendar <parameter> %}. Alors que mon modèle d'étiquette était ok, qui appelle la valeur renvoyée de la fonction tag:

{{calendrier}}

Répondre

1

Votre erreur de récursion est due au fait que vous appelez la balise calendar dans le modèle rendu par cette même balise.

Votre fichier /tags/my_calendar.html devrait effectivement ressembler à ceci:

<div> 
{{ calendar }} 
</div> 

Notez l'utilisation de la syntaxe de variable, pour vous montrer que vous rendre la valeur passée dans le contexte, plutôt que la balise syntaxe. Vous n'avez pas non plus besoin d'utiliser load.

0

Si le calendrier va être affiché dans chaque page de votre site, il fait plus de sens pour créer le contrôleur du calendrier dans un context_processor. De cette façon, les champs sont ajoutés à l'objet Request disponible pour chaque modèle, puis il suffit d'intégrer l'affichage du calendrier dans votre modèle de base.

James Bennet décrit clairement: http://www.b-list.org/weblog/2006/jun/14/django-tips-template-context-processors/

Si vous attachez l'appel au calendrier comme une fermeture ou un objet foncteur, en passant, vous pouvez éviter les frais de transaction sur les pages où vous ne le rend pas . C'est ce que fait QuerySet, et pourquoi il ne traite pas avec la base de données tant que les données ne sont pas réellement demandées.

+0

@ Elf Sternberg: Je garderai une trace de votre référence. Merci. – saeed

+0

@ Daniel Roseman: quand j'utilise la syntaxe de la variable, je ne reçois plus d'erreur de récurrence, mais mon calendrier n'est toujours pas affiché. Je ne peux pas expliquer son comportement. Je vais chercher le problème. – saeed

Questions connexes