PDF période formation
This commit is contained in:
parent
83cca59c7e
commit
96100f13c6
12 changed files with 410 additions and 367 deletions
|
|
@ -69,7 +69,7 @@ class Domaine(models.Model):
|
||||||
return '{0} - {1}'.format(self.code, self.nom)
|
return '{0} - {1}'.format(self.code, self.nom)
|
||||||
|
|
||||||
def url(self):
|
def url(self):
|
||||||
return "<a href='/domaine/{0}'>{1}</a>".format(self.id, self.__str__())
|
return "<a href='/domaine/{0}'>{1}</a>".format(self.pk, self.__str__())
|
||||||
|
|
||||||
|
|
||||||
class Processus(models.Model):
|
class Processus(models.Model):
|
||||||
|
|
@ -86,7 +86,7 @@ class Processus(models.Model):
|
||||||
return '{0} - {1}'.format(self.code, self.nom)
|
return '{0} - {1}'.format(self.code, self.nom)
|
||||||
|
|
||||||
def url(self):
|
def url(self):
|
||||||
return "<a href='/processus/{0}'>{1}</a>".format(self.id, self.__str__())
|
return "<a href='/processus/{0}'>{1}</a>".format(self.pk, self.__str__())
|
||||||
|
|
||||||
|
|
||||||
class Module(models.Model):
|
class Module(models.Model):
|
||||||
|
|
@ -121,10 +121,10 @@ class Module(models.Model):
|
||||||
return '{0} - {1}'.format(self.code, self.nom)
|
return '{0} - {1}'.format(self.code, self.nom)
|
||||||
|
|
||||||
def url(self):
|
def url(self):
|
||||||
return "<a href='/module/{0}'>{1}</a>".format(self.id, self.__str__())
|
return "<a href='/module/{0}'>{1}</a>".format(self.pk, self.__str__())
|
||||||
|
|
||||||
def url_code(self):
|
def url_code(self):
|
||||||
return "<a href='/module/{0}' title='{2}'>{1}</a>".format(self.id, self.code, self.nom)
|
return "<a href='/module/{0}' title=\"{2}\">{1}</a>".format(self.pk, self.code, self.nom)
|
||||||
|
|
||||||
|
|
||||||
class Competence(models.Model):
|
class Competence(models.Model):
|
||||||
|
|
@ -209,12 +209,16 @@ class PDFResponse(HttpResponse):
|
||||||
t = Table(data, colWidths=[8*cm, 8*cm])
|
t = Table(data, colWidths=[8*cm, 8*cm])
|
||||||
else:
|
else:
|
||||||
t = Table(data, colWidths=[11*cm, 11*cm])
|
t = Table(data, colWidths=[11*cm, 11*cm])
|
||||||
t.setStyle(TableStyle([
|
t.setStyle(
|
||||||
('ALIGN', (0, 0), (0, 0), 'LEFT'),
|
TableStyle(
|
||||||
('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
|
[
|
||||||
('LINEABOVE', (0, 0), (-1, -1), 0.5, colors.black),
|
('ALIGN', (0, 0), (0, 0), 'LEFT'),
|
||||||
('LINEBELOW', (0, -1), (-1, -1), 0.5, colors.black),
|
('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
|
||||||
]))
|
('LINEABOVE', (0, 0), (-1, -1), 0.5, colors.black),
|
||||||
|
('LINEBELOW', (0, -1), (-1, -1), 0.5, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
t.hAlign = TA_LEFT
|
t.hAlign = TA_LEFT
|
||||||
self.story.append(t)
|
self.story.append(t)
|
||||||
|
|
||||||
|
|
|
||||||
307
cms/pdf.py
307
cms/pdf.py
|
|
@ -2,21 +2,230 @@
|
||||||
from django.http.response import HttpResponse
|
from django.http.response import HttpResponse
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from reportlab.pdfgen import canvas
|
from reportlab.platypus import SimpleDocTemplate, Spacer, Frame, Paragraph, Preformatted
|
||||||
from reportlab.platypus import SimpleDocTemplate, Frame
|
|
||||||
from reportlab.platypus import Table, TableStyle, Image
|
from reportlab.platypus import Table, TableStyle, Image
|
||||||
from reportlab.lib.pagesizes import A4, landscape
|
from reportlab.lib.pagesizes import A4, landscape
|
||||||
from reportlab.lib.units import cm
|
from reportlab.lib.units import cm
|
||||||
from reportlab.lib.enums import TA_LEFT, TA_CENTER
|
from reportlab.lib.enums import TA_LEFT, TA_CENTER
|
||||||
from reportlab.lib import colors
|
from reportlab.lib import colors
|
||||||
from reportlab.lib.styles import ParagraphStyle as PS
|
from reportlab.lib.colors import HexColor
|
||||||
|
from reportlab.lib.styles import ParagraphStyle as ps
|
||||||
|
from reportlab.pdfgen import canvas
|
||||||
|
|
||||||
|
style_8_c = ps(name='CORPS', fontName='Helvetica', fontSize=6, alignment=TA_CENTER)
|
||||||
|
style_normal = ps(name='CORPS', fontName='Helvetica', fontSize=9, alignment=TA_LEFT)
|
||||||
|
style_bold = ps(name='CORPS', fontName='Helvetica-Bold', fontSize=10, alignment=TA_LEFT, leftIndent=0.3*cm)
|
||||||
|
style_title = ps(name='CORPS', fontName='Helvetica', fontSize=12, alignment=TA_LEFT)
|
||||||
|
style_adress = ps(name='CORPS', fontName='Helvetica', fontSize=10, alignment=TA_LEFT, leftIndent=300)
|
||||||
|
|
||||||
|
|
||||||
style_8_c = PS(name='CORPS', fontName='Helvetica', fontSize=6, alignment=TA_CENTER)
|
class MyDocTemplateES(SimpleDocTemplate):
|
||||||
style_normal = PS(name='CORPS', fontName='Helvetica', fontSize=8, alignment=TA_LEFT)
|
def __init__(self, filename, title_left, title_right, portrait=True):
|
||||||
style_bold = PS(name='CORPS', fontName='Helvetica-Bold', fontSize=10, alignment=TA_LEFT)
|
if portrait is True:
|
||||||
style_title = PS(name='CORPS', fontName='Helvetica', fontSize=12, alignment=TA_LEFT)
|
page_size = A4
|
||||||
style_adress = PS(name='CORPS', fontName='Helvetica', fontSize=10, alignment=TA_LEFT, leftIndent=300)
|
column_width = 8 * cm
|
||||||
|
else:
|
||||||
|
page_size = landscape(A4)
|
||||||
|
column_width = 13 * cm
|
||||||
|
SimpleDocTemplate.__init__(self, filename, pagesize=page_size,
|
||||||
|
topMargin=0 * cm,
|
||||||
|
leftMargin=2 * cm,
|
||||||
|
rightMargin=2 * cm,
|
||||||
|
bottomMargin=0.5 * cm,
|
||||||
|
)
|
||||||
|
self.fileName = filename
|
||||||
|
im1 = Image(settings.MEDIA_ROOT + 'logo_EPC.png', width=170, height=80)
|
||||||
|
im2 = Image(settings.MEDIA_ROOT + 'logo_ESNE.png', width=170, height=80)
|
||||||
|
data = list()
|
||||||
|
data.append([im1, im2])
|
||||||
|
data.append([Spacer(0, 0.5 * cm)])
|
||||||
|
data.append([title_left, title_right])
|
||||||
|
t = Table(data, colWidths=[column_width] * 2, hAlign=TA_LEFT)
|
||||||
|
t.setStyle(
|
||||||
|
TableStyle(
|
||||||
|
[
|
||||||
|
('SIZE', (0, 0), (-1, -1), 9),
|
||||||
|
('FONT', (0, 0), (-1, -1), 'Helvetica-Bold'),
|
||||||
|
('ALIGN', (0, 0), (0, 0), 'LEFT'),
|
||||||
|
('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
|
||||||
|
('LINEABOVE', (0, 2), (-1, 2), 0.5, colors.black),
|
||||||
|
('LINEBELOW', (0, -1), (-1, -1), 0.5, colors.black),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.flowable.append(t)
|
||||||
|
|
||||||
|
def beforePage(self):
|
||||||
|
# page number
|
||||||
|
self.canv.saveState()
|
||||||
|
self.canv.setFontSize(8)
|
||||||
|
self.canv.drawCentredString(self.pagesize[0] / 2, 0.5 * cm, "Page : " + str(self.canv.getPageNumber()))
|
||||||
|
self.canv.restoreState()
|
||||||
|
|
||||||
|
|
||||||
|
class ModulePdf(MyDocTemplateES):
|
||||||
|
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.flowable = list()
|
||||||
|
MyDocTemplateES.__init__(self, filename, 'Formation EDS', 'Module de formation', portrait=True)
|
||||||
|
|
||||||
|
def preformatted_left(self, txt):
|
||||||
|
return Preformatted(txt, style_normal, maxLineLength=15)
|
||||||
|
|
||||||
|
def preformatted_right(self, txt):
|
||||||
|
return Preformatted(txt, style_normal, maxLineLength=90)
|
||||||
|
|
||||||
|
def produce(self, module):
|
||||||
|
str_comp = ''
|
||||||
|
for c in module.competence_set.all():
|
||||||
|
str_comp += '- {0} ({1})\n'.format(c.nom, c.code)
|
||||||
|
"""
|
||||||
|
if self.request.user.is_authenticated:
|
||||||
|
|
||||||
|
for sc in c.souscompetence_set.all():
|
||||||
|
str_comp += ' -- {0}\n'.format(sc.nom)
|
||||||
|
"""
|
||||||
|
|
||||||
|
str_scom = ''
|
||||||
|
for c in module.competence_set.all():
|
||||||
|
for sc in c.souscompetence_set.all():
|
||||||
|
str_scom += '- {0} (voir {1})\n'.format(sc.nom, c.code)
|
||||||
|
|
||||||
|
str_res = ''
|
||||||
|
for c in module.ressource_set.all():
|
||||||
|
str_res += '- {0}\n'.format(c.nom)
|
||||||
|
|
||||||
|
str_obj = ''
|
||||||
|
for c in module.objectif_set.all():
|
||||||
|
str_obj += '- {0}\n'.format(c.nom)
|
||||||
|
|
||||||
|
lines = module.contenu.split('\n')
|
||||||
|
str_con = ''
|
||||||
|
for l in lines:
|
||||||
|
str_con += '{0}\n'.format(l)
|
||||||
|
|
||||||
|
self.flowable.append(Spacer(0, 0.5 * cm))
|
||||||
|
self.flowable.append(Paragraph(module.__str__(), style_bold, ))
|
||||||
|
self.flowable.append(Spacer(0, 0.5 * cm))
|
||||||
|
|
||||||
|
data = [
|
||||||
|
[self.preformatted_left('Domaine'), self.preformatted_right(module.processus.domaine.__str__())],
|
||||||
|
[self.preformatted_left('Processus'), self.preformatted_right(module.processus.__str__())],
|
||||||
|
[self.preformatted_left('Situation emblématique'), self.preformatted_right(module.situation)],
|
||||||
|
[self.preformatted_left('Compétences visées'), self.preformatted_right(str_comp)],
|
||||||
|
[self.preformatted_left('Plus-value sur le CFC ASE'), self.preformatted_right(str_scom)],
|
||||||
|
# [Preformatted_left('Ressources à acquérir'), Preformatted_right(str_res)],
|
||||||
|
[self.preformatted_left('Objectifs à atteindre'), self.preformatted_right(str_obj)],
|
||||||
|
[self.preformatted_left('Didactique'), self.preformatted_right(module.didactique)],
|
||||||
|
# [Preformatted_left('Contenu'), Preformatted_right(str_con)],
|
||||||
|
[self.preformatted_left('Evaluation'), self.preformatted_right(module.evaluation)],
|
||||||
|
[self.preformatted_left('Type'), self.preformatted_right('{0}, obligatoire'.format(module.type))],
|
||||||
|
[self.preformatted_left('Semestre'), self.preformatted_right('Sem. {0}'.format(module.semestre))],
|
||||||
|
[self.preformatted_left('Présentiel'),
|
||||||
|
self.preformatted_right('{0} heures'.format(module.periode_presentiel))],
|
||||||
|
[self.preformatted_left('Travail personnel'),
|
||||||
|
self.preformatted_right('{0} heures'.format(module.travail_perso))],
|
||||||
|
[self.preformatted_left('Responsable'),
|
||||||
|
self.preformatted_right(module.processus.domaine.responsable.descr_pdf())],
|
||||||
|
]
|
||||||
|
t = Table(data, colWidths=[3*cm, 13*cm])
|
||||||
|
t.hAlign = TA_CENTER
|
||||||
|
t.setStyle(
|
||||||
|
TableStyle([
|
||||||
|
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
|
||||||
|
('VALIGN', (0, 0), (-1, -1), 'TOP'),
|
||||||
|
('LEFTPADDING', (0, 0), (-1, -1), 0), ]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.flowable.append(t)
|
||||||
|
self.build(self.flowable)
|
||||||
|
|
||||||
|
|
||||||
|
class PlanFormationPdf(MyDocTemplateES):
|
||||||
|
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.flowable = list()
|
||||||
|
MyDocTemplateES.__init__(self, filename, 'Formation EDS', 'Plan de formation', portrait=False)
|
||||||
|
|
||||||
|
def formating(self, el1='', length=40):
|
||||||
|
el1 = '' if el1 == '' else el1.__str__()
|
||||||
|
return Preformatted(el1, style_normal, maxLineLength=length)
|
||||||
|
|
||||||
|
def produce(self, domain, process):
|
||||||
|
data = [
|
||||||
|
['Domaines', 'Processus', 'Sem1', 'Sem2', 'Sem3', 'Sem4', 'Sem5', 'Sem6'],
|
||||||
|
[self.formating(domain[0]), self.formating(process[0], 60), 'M01', '', '', '', '', ''],
|
||||||
|
[self.formating(''), self.formating('', 60), 'M02', '', '', '', '', ''],
|
||||||
|
[self.formating(''), self.formating(process[1], 60), '', '', '', 'M03', '', ''],
|
||||||
|
[self.formating(''), self.formating('', 60), '', 'M04', '', '', '', ''],
|
||||||
|
[self.formating(domain[1]), self.formating(process[2], 60), 'M05', '', 'M06', '', '', ''],
|
||||||
|
[self.formating(''), self.formating(process[3], 60), '', '', '', '', 'M07', 'M09'],
|
||||||
|
[self.formating(''), self.formating('', 60), '', '', '', '', 'M08', ''],
|
||||||
|
[self.formating(domain[2]), self.formating(process[4], 60), '', '', 'M10', '', 'M12'],
|
||||||
|
[self.formating(''), self.formating(process[5], 60), '', '', 'M11', '', ''],
|
||||||
|
[self.formating(domain[3]), self.formating(process[6], 60), '', '', 'M13', '', '', 'M14'],
|
||||||
|
[self.formating(domain[4]), self.formating(process[7], 60), 'M15', '', '', '', '', ''],
|
||||||
|
[self.formating(domain[5]), self.formating(process[8], 60), 'M16_1', '', 'M16_2', '', 'M16_3', ''],
|
||||||
|
[self.formating(domain[6]), self.formating(process[9], 60), 'M17_1', '', 'M17_2', '', 'M17_3', ''],
|
||||||
|
[self.formating(domain[7]), self.formating(process[10], 60), 'Macc', '', '', '', '', ''],
|
||||||
|
]
|
||||||
|
t = Table(data, colWidths=[7*cm, 9*cm, 1.5*cm, 1.5*cm, 1.5*cm, 1.5*cm, 1.5*cm, 1.5*cm],
|
||||||
|
spaceBefore=0.5*cm, spaceAfter=1*cm)
|
||||||
|
t.setStyle(TableStyle([
|
||||||
|
('SIZE', (0, 0), (-1, -1), 8),
|
||||||
|
('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'),
|
||||||
|
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
|
||||||
|
('ALIGN', (2, 0), (-1, -1), 'CENTER'),
|
||||||
|
('GRID', (0, 0), (-1, -1), 0.25, colors.black),
|
||||||
|
# Domaine 1
|
||||||
|
('SPAN', (0, 1), (0, 4)),
|
||||||
|
('SPAN', (1, 1), (1, 2)),
|
||||||
|
('SPAN', (1, 3), (1, 4)),
|
||||||
|
('BACKGROUND', (0, 1), (1, 4), colors.orange),
|
||||||
|
('BACKGROUND', (2, 1), (2, 2), colors.orange),
|
||||||
|
('BACKGROUND', (5, 3), (5, 3), colors.orange),
|
||||||
|
('BACKGROUND', (3, 4), (3, 4), colors.orange),
|
||||||
|
# Domaine 2
|
||||||
|
('SPAN', (0, 5), (0, 7)),
|
||||||
|
('BACKGROUND', (0, 5), (1, 7), colors.red),
|
||||||
|
('BACKGROUND', (2, 5), (2, 5), colors.red),
|
||||||
|
('BACKGROUND', (4, 5), (4, 5), colors.red),
|
||||||
|
('BACKGROUND', (6, 6), (6, 6), colors.red),
|
||||||
|
('BACKGROUND', (7, 6), (7, 6), colors.red),
|
||||||
|
('BACKGROUND', (6, 7), (6, 7), colors.red),
|
||||||
|
# Domaine 3
|
||||||
|
('SPAN', (0, 8), (0, 9)),
|
||||||
|
('SPAN', (1, 6), (1, 7)),
|
||||||
|
('SPAN', (4, 8), (5, 8)),
|
||||||
|
('SPAN', (4, 9), (5, 9)),
|
||||||
|
('BACKGROUND', (0, 8), (1, 9), colors.pink),
|
||||||
|
('BACKGROUND', (4, 8), (6, 8), colors.pink),
|
||||||
|
('BACKGROUND', (4, 9), (5, 9), colors.pink),
|
||||||
|
# Domaine 4
|
||||||
|
('BACKGROUND', (0, 10), (1, 10), HexColor('#AD7FA8')),
|
||||||
|
('BACKGROUND', (4, 10), (4, 10), HexColor('#AD7FA8')),
|
||||||
|
('BACKGROUND', (7, 10), (7, 10), HexColor('#AD7FA8')),
|
||||||
|
# Domaine 5
|
||||||
|
('SPAN', (2, 11), (-1, 11)),
|
||||||
|
('BACKGROUND', (0, 11), (-1, 11), HexColor('#729FCF')),
|
||||||
|
# Domaine 6
|
||||||
|
('SPAN', (2, 12), (3, 12)),
|
||||||
|
('SPAN', (4, 12), (5, 12)),
|
||||||
|
('SPAN', (6, 12), (7, 12)),
|
||||||
|
('BACKGROUND', (0, 12), (-1, 12), colors.lightgreen),
|
||||||
|
# Domaine 7
|
||||||
|
('SPAN', (2, 13), (3, 13)),
|
||||||
|
('SPAN', (4, 13), (5, 13)),
|
||||||
|
('SPAN', (6, 13), (7, 13)),
|
||||||
|
('BACKGROUND', (0, 13), (-1, 13), colors.white),
|
||||||
|
# Domaine 8
|
||||||
|
('SPAN', (2, 14), (-1, 14)),
|
||||||
|
('BACKGROUND', (0, 14), (-1, 14), colors.lightgrey),
|
||||||
|
|
||||||
|
]))
|
||||||
|
t.hAlign = TA_CENTER
|
||||||
|
self.flowable.append(t)
|
||||||
|
self.build(self.flowable)
|
||||||
|
|
||||||
|
|
||||||
class PDFResponse(HttpResponse):
|
class PDFResponse(HttpResponse):
|
||||||
|
|
@ -45,73 +254,31 @@ class PDFResponse(HttpResponse):
|
||||||
self.story.append(t)
|
self.story.append(t)
|
||||||
|
|
||||||
|
|
||||||
class MyDocTemplate(SimpleDocTemplate):
|
class PeriodeFormationPdf(SimpleDocTemplate):
|
||||||
|
|
||||||
def __init__(self, name):
|
|
||||||
SimpleDocTemplate.__init__(self, name, pagesize=A4, topMargin=0.5*cm, leftMargin=1*cm)
|
|
||||||
self.fileName = name
|
|
||||||
self.PAGE_WIDTH = A4[0]
|
|
||||||
self.PAGE_HEIGHT = A4[1]
|
|
||||||
self.CENTRE_WIDTH = self.PAGE_WIDTH/2.0
|
|
||||||
self.CENTRE_HEIGHT = self.PAGE_HEIGHT/2.0
|
|
||||||
|
|
||||||
def beforePage(self):
|
|
||||||
# page number
|
|
||||||
self.canv.saveState()
|
|
||||||
self.canv.setFontSize(8)
|
|
||||||
self.canv.drawCentredString(self.CENTRE_WIDTH, 1*cm, "Page : " + str(self.canv.getPageNumber()))
|
|
||||||
self.canv.restoreState()
|
|
||||||
|
|
||||||
|
|
||||||
class MyDocTemplateLandscape(SimpleDocTemplate):
|
|
||||||
|
|
||||||
def __init__(self, name):
|
|
||||||
SimpleDocTemplate.__init__(self, name, pagesize=landscape(A4), topMargin=0*cm, leftMargin=2*cm)
|
|
||||||
self.fileName = name
|
|
||||||
self.PAGE_WIDTH = A4[1]
|
|
||||||
self.PAGE_HEIGHT = A4[0]
|
|
||||||
self.CENTRE_WIDTH = self.PAGE_WIDTH/2.0
|
|
||||||
self.CENTRE_HEIGHT = self.PAGE_HEIGHT/2.0
|
|
||||||
|
|
||||||
def beforePage(self):
|
|
||||||
# page number
|
|
||||||
self.canv.saveState()
|
|
||||||
self.canv.setFontSize(8)
|
|
||||||
self.canv.drawCentredString(self.CENTRE_WIDTH, 1*cm, "Page : " + str(self.canv.getPageNumber()))
|
|
||||||
self.canv.restoreState()
|
|
||||||
|
|
||||||
|
|
||||||
class PeriodPDF(object):
|
|
||||||
"""Imprime les heures de cours par semestre"""
|
"""Imprime les heures de cours par semestre"""
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
self.canv = canvas.Canvas(filename, pagesize=A4)
|
self.flowable = list()
|
||||||
self.canv.setPageCompression(0)
|
#SimpleDocTemplate.__init__(self, filename) #, 'Formation EDS', 'Périodes de la formation', portrait=True)
|
||||||
self.canv.setFont('Helvetica', 9)
|
c = canvas.Canvas(filename, pagesize=A4)
|
||||||
header_frame = Frame(1.2*cm, 24*cm, 18*cm, 5*cm, showBoundary=0)
|
width, height = A4
|
||||||
story = []
|
im1 = Image(settings.MEDIA_ROOT + 'logo_EPC.png', width=120, height=80)
|
||||||
image = Image(settings.MEDIA_ROOT + 'logo.png', width=520, height=90)
|
im2 = Image(settings.MEDIA_ROOT + 'logo_ESNE.png', width=120, height=80)
|
||||||
story.append(image)
|
c.drawImage(settings.MEDIA_ROOT + 'logo_EPC.png', 0, height - 1*cm) # Who needs consistency?
|
||||||
data = [['Filières EDS', 'Périodes de formation']]
|
c.drawImage(settings.MEDIA_ROOT + 'logo_ESNE.png', 8*cm, height-1*cm)
|
||||||
t = Table(data, colWidths=[8.5*cm, 8.5*cm], spaceBefore=0, spaceAfter=0, hAlign=TA_LEFT)
|
c.showPage()
|
||||||
t.setStyle(TableStyle([
|
c.save()
|
||||||
('ALIGN', (0, 0), (0, 0), 'LEFT'),
|
|
||||||
('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
|
|
||||||
('LINEABOVE', (0, 0), (-1, -1), 0.5, colors.black),
|
|
||||||
('LINEBELOW', (0, -1), (-1, -1), 0.5, colors.black),
|
|
||||||
]))
|
|
||||||
story.append(t)
|
|
||||||
header_frame.addFromList(story, self.canv)
|
|
||||||
|
|
||||||
def produce_half_year(self, half_year_id, modules, total):
|
|
||||||
|
def produce_half_year(self, half_year_id, modules, total, canv):
|
||||||
initial_pos_x = [2, 11]
|
initial_pos_x = [2, 11]
|
||||||
initial_pos_y = [17, 17, 10, 10, 3, 3]
|
initial_pos_y = [17, 17, 10, 10, 3, 3]
|
||||||
width = 7*cm
|
width = 7.5*cm
|
||||||
height = 6.5*cm
|
height = 6.5*cm
|
||||||
|
|
||||||
x = initial_pos_x[(half_year_id-1) % 2]*cm
|
x = initial_pos_x[(half_year_id-1) % 2]*cm
|
||||||
y = initial_pos_y[half_year_id-1]*cm
|
y = initial_pos_y[half_year_id-1]*cm
|
||||||
|
|
||||||
my_frame = Frame(x, y, width, height, showBoundary=0)
|
my_frame = Frame(x, y, width, height, showBoundary=1)
|
||||||
data = [['Semestre {0}'.format(half_year_id), '{0} h.'.format(total)]]
|
data = [['Semestre {0}'.format(half_year_id), '{0} h.'.format(total)]]
|
||||||
for line in modules:
|
for line in modules:
|
||||||
value = getattr(line, 'sem{0}'.format(half_year_id))
|
value = getattr(line, 'sem{0}'.format(half_year_id))
|
||||||
|
|
@ -122,8 +289,10 @@ class PeriodPDF(object):
|
||||||
('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
|
('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
|
||||||
('LINEBELOW', (0, 0), (1, 0), 1, colors.black),
|
('LINEBELOW', (0, 0), (1, 0), 1, colors.black),
|
||||||
('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ]))
|
('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ]))
|
||||||
story = [t]
|
|
||||||
my_frame.addFromList(story, self.canv)
|
|
||||||
|
|
||||||
def print_total(self, total):
|
self.flowable.append(t)
|
||||||
self.canv.drawString(2*cm, 2*cm, 'Total de la formation: {0} heures'.format(total))
|
my_frame.addFromList(self.flowable, canv)
|
||||||
|
# self.build(self.flowable)
|
||||||
|
|
||||||
|
def print_total(self, total, canv):
|
||||||
|
canv.drawString(2*cm, 2*cm, 'Total de la formation: {0} heures'.format(total))
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@CHARSET "UTF-8";
|
@CHARSET "UTF-8";
|
||||||
|
|
||||||
|
|
||||||
#submenu {
|
#submenu {
|
||||||
width:100%;
|
width:100%;
|
||||||
background: #79aec8;
|
background: #79aec8;
|
||||||
padding: 10px 40px;
|
padding: 10px 40px;
|
||||||
|
|
|
||||||
331
cms/views.py
331
cms/views.py
|
|
@ -4,21 +4,15 @@ Created on 4 déc. 2012
|
||||||
@author: alzo
|
@author: alzo
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from django.views.generic import ListView, TemplateView, DetailView
|
from django.views.generic import ListView, TemplateView, DetailView
|
||||||
from django.db.models import F, Sum
|
from django.db.models import F, Sum
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.conf import settings
|
from reportlab.pdfgen import canvas
|
||||||
from reportlab.platypus import Paragraph, Spacer, Table, TableStyle, Preformatted
|
|
||||||
from reportlab.lib.units import cm
|
|
||||||
from reportlab.lib import colors
|
|
||||||
from reportlab.lib.colors import HexColor
|
|
||||||
|
|
||||||
from cms.pdf import PeriodPDF
|
from cms.pdf import PeriodeFormationPdf, ModulePdf, PlanFormationPdf
|
||||||
from .models import style_normal, style_title
|
from cms.models import (Domaine, Processus, Module, Competence, Document, UploadDoc,)
|
||||||
from .models import (Domaine, Processus, Module, Competence, Document, UploadDoc,
|
|
||||||
PDFResponse, MyDocTemplate, MyDocTemplateLandscape)
|
|
||||||
# Create your views here.
|
|
||||||
|
|
||||||
|
|
||||||
class HomeView(TemplateView):
|
class HomeView(TemplateView):
|
||||||
|
|
@ -34,109 +28,6 @@ class HomeView(TemplateView):
|
||||||
context[m.code] = m
|
context[m.code] = m
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class Element(object):
|
|
||||||
|
|
||||||
def __init__(self, el):
|
|
||||||
self.txt = el.__str__()
|
|
||||||
|
|
||||||
|
|
||||||
class HomePDFView(TemplateView):
|
|
||||||
template_name = 'cms/index.html'
|
|
||||||
|
|
||||||
def formating(self, el1='', length=40):
|
|
||||||
el1 = '' if el1 == '' else el1.__str__()
|
|
||||||
return Preformatted(el1, style_normal, maxLineLength=length)
|
|
||||||
|
|
||||||
# def pf40(self, txt):
|
|
||||||
# return Preformatted(txt, style_normal, maxLineLength=40)
|
|
||||||
|
|
||||||
def render_to_response(self, context, **response_kwargs):
|
|
||||||
|
|
||||||
response = PDFResponse('PlanFormation.pdf', 'Plan de formation', portrait=False)
|
|
||||||
d = Domaine.objects.all().order_by('code')
|
|
||||||
p = Processus.objects.all().order_by('code')
|
|
||||||
|
|
||||||
data = [
|
|
||||||
['Domaines', 'Processus', 'Sem1', 'Sem2', 'Sem3', 'Sem4', 'Sem5', 'Sem6'],
|
|
||||||
[self.formating(d[0]), self.formating(p[0], 60), 'M01', '', '', '', '', ''],
|
|
||||||
[self.formating(''), self.formating('', 60), 'M02', '', '', '', '', ''],
|
|
||||||
[self.formating(''), self.formating(p[1], 60), '', '', '', 'M03', '', ''],
|
|
||||||
[self.formating(''), self.formating('', 60), '', 'M04', '', '', '', ''],
|
|
||||||
[self.formating(d[1]), self.formating(p[2], 60), 'M05', '', 'M06', '', '', ''],
|
|
||||||
[self.formating(''), self.formating(p[3], 60), '', '', '', '', 'M07', 'M09'],
|
|
||||||
[self.formating(''), self.formating('', 60), '', '', '', '', 'M08', ''],
|
|
||||||
[self.formating(d[2]), self.formating(p[4], 60), '', '', 'M10', '', 'M12'],
|
|
||||||
[self.formating(''), self.formating(p[5], 60), '', '', 'M11', '', ''],
|
|
||||||
[self.formating(d[3]), self.formating(p[6], 60), '', '', 'M13', '', '', 'M14'],
|
|
||||||
[self.formating(d[4]), self.formating(p[7], 60), 'M15', '', '', '', '', ''],
|
|
||||||
[self.formating(d[5]), self.formating(p[8], 60), 'M16_1', '', 'M16_2', '', 'M16_3', ''],
|
|
||||||
[self.formating(d[6]), self.formating(p[9], 60), 'M17_1', '', 'M17_2', '', 'M17_3', ''],
|
|
||||||
[self.formating(d[7]), self.formating(p[10], 60), 'Macc', '', '', '', '', ''],
|
|
||||||
]
|
|
||||||
|
|
||||||
print(data)
|
|
||||||
|
|
||||||
t = Table(data, colWidths=[5.5*cm, 8*cm, 1.5*cm, 1.5*cm, 1.5*cm, 1.5*cm, 1.5*cm, 1.5*cm],
|
|
||||||
spaceBefore=0.5*cm, spaceAfter=1*cm)
|
|
||||||
t.setStyle(TableStyle([
|
|
||||||
('SIZE', (0, 0), (-1, -1), 8),
|
|
||||||
('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'),
|
|
||||||
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
|
|
||||||
('ALIGN', (2, 0), (-1, -1), 'CENTER'),
|
|
||||||
('GRID', (0, 0), (-1, -1), 0.25, colors.black),
|
|
||||||
# Domaine 1
|
|
||||||
('SPAN', (0, 1), (0, 4)),
|
|
||||||
('SPAN', (1, 1), (1, 2)),
|
|
||||||
('SPAN', (1, 3), (1, 4)),
|
|
||||||
('BACKGROUND', (0, 1), (1, 4), colors.orange),
|
|
||||||
('BACKGROUND', (2, 1), (2, 2), colors.orange),
|
|
||||||
('BACKGROUND', (5, 3), (5, 3), colors.orange),
|
|
||||||
('BACKGROUND', (3, 4), (3, 4), colors.orange),
|
|
||||||
# Domaine 2
|
|
||||||
('SPAN', (0, 5), (0, 7)),
|
|
||||||
('BACKGROUND', (0, 5), (1, 7), colors.red),
|
|
||||||
('BACKGROUND', (2, 5), (2, 5), colors.red),
|
|
||||||
('BACKGROUND', (4, 5), (4, 5), colors.red),
|
|
||||||
('BACKGROUND', (6, 6), (6, 6), colors.red),
|
|
||||||
('BACKGROUND', (7, 6), (7, 6), colors.red),
|
|
||||||
('BACKGROUND', (6, 7), (6, 7), colors.red),
|
|
||||||
# Domaine 3
|
|
||||||
('SPAN', (0, 8), (0, 9)),
|
|
||||||
('SPAN', (1, 6), (1, 7)),
|
|
||||||
('SPAN', (4, 8), (5, 8)),
|
|
||||||
('SPAN', (4, 9), (5, 9)),
|
|
||||||
('BACKGROUND', (0, 8), (1, 9), colors.pink),
|
|
||||||
('BACKGROUND', (4, 8), (6, 8), colors.pink),
|
|
||||||
('BACKGROUND', (4, 9), (5, 9), colors.pink),
|
|
||||||
# Domaine 4
|
|
||||||
('BACKGROUND', (0, 10), (1, 10), HexColor('#AD7FA8')),
|
|
||||||
('BACKGROUND', (4, 10), (4, 10), HexColor('#AD7FA8')),
|
|
||||||
('BACKGROUND', (7, 10), (7, 10), HexColor('#AD7FA8')),
|
|
||||||
# Domaine 5
|
|
||||||
('SPAN', (2, 11), (-1, 11)),
|
|
||||||
('BACKGROUND', (0, 11), (-1, 11), HexColor('#729FCF')),
|
|
||||||
# Domaine 6
|
|
||||||
('SPAN', (2, 12), (3, 12)),
|
|
||||||
('SPAN', (4, 12), (5, 12)),
|
|
||||||
('SPAN', (6, 12), (7, 12)),
|
|
||||||
('BACKGROUND', (0, 12), (-1, 12), colors.lightgreen),
|
|
||||||
# Domaine 7
|
|
||||||
('SPAN', (2, 13), (3, 13)),
|
|
||||||
('SPAN', (4, 13), (5, 13)),
|
|
||||||
('SPAN', (6, 13), (7, 13)),
|
|
||||||
('BACKGROUND', (0, 13), (-1, 13), colors.white),
|
|
||||||
# Domaine 8
|
|
||||||
('SPAN', (2, 14), (-1, 14)),
|
|
||||||
('BACKGROUND', (0, 14), (-1, 14), colors.lightgrey),
|
|
||||||
|
|
||||||
]))
|
|
||||||
t.hAlign = 0
|
|
||||||
response.story.append(t)
|
|
||||||
doc = MyDocTemplateLandscape(response)
|
|
||||||
doc.build(response.story)
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
class DomaineDetailView(DetailView):
|
class DomaineDetailView(DetailView):
|
||||||
template_name = 'cms/domaine_detail.html'
|
template_name = 'cms/domaine_detail.html'
|
||||||
|
|
@ -166,14 +57,6 @@ class ModuleDetailView(DetailView):
|
||||||
class ModuleListView(ListView):
|
class ModuleListView(ListView):
|
||||||
template_name = 'cms/module_list.html'
|
template_name = 'cms/module_list.html'
|
||||||
model = Module
|
model = Module
|
||||||
|
|
||||||
|
|
||||||
def preformatted_left(text):
|
|
||||||
return Preformatted(text, style_normal, maxLineLength=15)
|
|
||||||
|
|
||||||
|
|
||||||
def preformatted_right(text):
|
|
||||||
return Preformatted(text, style_normal, maxLineLength=110)
|
|
||||||
|
|
||||||
|
|
||||||
class EvaluationView(ListView):
|
class EvaluationView(ListView):
|
||||||
|
|
@ -212,88 +95,63 @@ class UploadDetailView(DetailView):
|
||||||
context = super(UploadDetailView, self).get_context_data(**kwargs)
|
context = super(UploadDetailView, self).get_context_data(**kwargs)
|
||||||
context['fichier'] = self.get_object().docfile.url
|
context['fichier'] = self.get_object().docfile.url
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class ModulePDF(DetailView):
|
|
||||||
template_name = 'cms/module_detail.html'
|
|
||||||
model = Module
|
|
||||||
|
|
||||||
def render_to_response(self, context, **response_kwargs):
|
|
||||||
m = self.get_object()
|
|
||||||
response = PDFResponse('Module_{0}.pdf'.format(m.code), 'Module de formation')
|
|
||||||
|
|
||||||
str_comp = ''
|
|
||||||
for c in m.competence_set.all():
|
|
||||||
str_comp += '- {0} ({1})\n'.format(c.nom, c.code)
|
|
||||||
"""
|
|
||||||
if self.request.user.is_authenticated:
|
|
||||||
|
|
||||||
for sc in c.souscompetence_set.all():
|
|
||||||
str_comp += ' -- {0}\n'.format(sc.nom)
|
|
||||||
"""
|
|
||||||
|
|
||||||
str_scom = ''
|
|
||||||
for c in m.competence_set.all():
|
|
||||||
for sc in c.souscompetence_set.all():
|
|
||||||
str_scom += '- {0} (voir {1})\n'.format(sc.nom, c.code)
|
|
||||||
|
|
||||||
str_res = ''
|
|
||||||
for c in m.ressource_set.all():
|
|
||||||
str_res += '- {0}\n'.format(c.nom)
|
|
||||||
|
|
||||||
str_obj = ''
|
|
||||||
for c in m.objectif_set.all():
|
|
||||||
str_obj += '- {0}\n'.format(c.nom)
|
|
||||||
|
|
||||||
lines = m.contenu.split('\n')
|
|
||||||
str_con = ''
|
|
||||||
for l in lines:
|
|
||||||
str_con += '{0}\n'.format(l)
|
|
||||||
|
|
||||||
response.story.append(Spacer(0, 1*cm))
|
|
||||||
response.story.append(Paragraph(m.__str__(), style_title))
|
|
||||||
|
|
||||||
data = [
|
|
||||||
[preformatted_left('Domaine'), preformatted_right(m.processus.domaine.__str__())],
|
|
||||||
[preformatted_left('Processus'), preformatted_right(m.processus.__str__())],
|
|
||||||
[preformatted_left('Situation emblématique'), preformatted_right(m.situation)],
|
|
||||||
[preformatted_left('Compétences visées'), preformatted_right(str_comp)],
|
|
||||||
[preformatted_left('Plus-value sur le CFC ASE'), preformatted_right(str_scom)],
|
|
||||||
# [Preformatted_left('Ressources à acquérir'), Preformatted_right(str_res)],
|
|
||||||
[preformatted_left('Objectifs à atteindre'), preformatted_right(str_obj)],
|
|
||||||
[preformatted_left('Didactique'), preformatted_right(m.didactique)],
|
|
||||||
# [Preformatted_left('Contenu'), Preformatted_right(str_con)],
|
|
||||||
[preformatted_left('Evaluation'), preformatted_right(m.evaluation)],
|
|
||||||
[preformatted_left('Type'), preformatted_right('{0}, obligatoire'.format(m.type))],
|
|
||||||
[preformatted_left('Semestre'), preformatted_right('Sem. {0}'.format(m.semestre))],
|
|
||||||
[preformatted_left('Présentiel'), preformatted_right('{0} heures'.format(m.periode_presentiel))],
|
|
||||||
[preformatted_left('Travail personnel'), preformatted_right('{0} heures'.format(m.travail_perso))],
|
|
||||||
[preformatted_left('Responsable'), preformatted_right(m.processus.domaine.responsable.descr_pdf())],
|
|
||||||
]
|
|
||||||
t = Table(data, colWidths=[2.5*cm, 10*cm])
|
|
||||||
t.setStyle(
|
|
||||||
TableStyle([
|
|
||||||
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
|
|
||||||
('VALIGN', (0, 0), (-1, -1), 'TOP'),
|
|
||||||
('LEFTPADDING', (0, 0), (-1, -1), 0), ]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
t.hAlign = 0
|
|
||||||
response.story.append(Spacer(0, 1*cm))
|
|
||||||
response.story.append(t)
|
|
||||||
|
|
||||||
doc = MyDocTemplate(response)
|
|
||||||
doc.build(response.story)
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
|
def print_module_pdf(request, pk):
|
||||||
|
filename = 'module.pdf'
|
||||||
|
path = os.path.join(tempfile.gettempdir(), filename)
|
||||||
|
pdf = ModulePdf(path)
|
||||||
|
module = Module.objects.get(pk=pk)
|
||||||
|
pdf.produce(module)
|
||||||
|
with open(path, mode='rb') as fh:
|
||||||
|
response = HttpResponse(fh.read(), content_type='application/pdf')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="EDS_module_{0}.pdf"'.format(module.code)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def print_plan_formation(request):
|
||||||
|
filename = 'plan_formation.pdf'
|
||||||
|
path = os.path.join(tempfile.gettempdir(), filename)
|
||||||
|
pdf = PlanFormationPdf(path)
|
||||||
|
domain = Domaine.objects.all().order_by('code')
|
||||||
|
process = Processus.objects.all().order_by('code')
|
||||||
|
pdf.produce(domain, process)
|
||||||
|
|
||||||
|
with open(path, mode='rb') as fh:
|
||||||
|
response = HttpResponse(fh.read(), content_type='application/pdf')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="EDS_plan_formation.pdf"'
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def print_periode_formation(request):
|
||||||
|
filename = 'periode_formation.pdf'
|
||||||
|
path = os.path.join(tempfile.gettempdir(), filename)
|
||||||
|
pdf = PeriodeFormationPdf(path)
|
||||||
|
context = {}
|
||||||
|
context = get_context(context)
|
||||||
|
canv = canvas.Canvas(filename)
|
||||||
|
|
||||||
|
for semestre_id in range(1, 7):
|
||||||
|
modules = context['sem{0}'.format(str(semestre_id))]
|
||||||
|
total = context['tot{0}'.format(str(semestre_id))]
|
||||||
|
pdf.produce_half_year(semestre_id, modules, total, canv)
|
||||||
|
|
||||||
|
pdf.print_total(context['tot'], canv)
|
||||||
|
|
||||||
|
canv.save()
|
||||||
|
|
||||||
|
with open(filename, mode='rb') as fh:
|
||||||
|
response = HttpResponse(fh.read(), content_type='application/pdf')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename="{0}"'.format(filename)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def get_context(context):
|
def get_context(context):
|
||||||
"""
|
"""
|
||||||
Calcul du nombre de périodes de formation
|
Calcul du nombre de périodes de formation
|
||||||
"""
|
"""
|
||||||
liste = Module.objects.exclude(periode_presentiel=0)
|
liste = Module.objects.exclude(periode_presentiel=0)
|
||||||
# context['tot'] = liste.aggregate(Sum(F('periode_presentiel')))
|
# context['tot'] = liste.aggregate(Sum(F('periode_presentiel')))
|
||||||
|
|
||||||
context['sem1'] = liste.exclude(sem1=0)
|
context['sem1'] = liste.exclude(sem1=0)
|
||||||
context['tot1'] = liste.aggregate(Sum(F('sem1')))['sem1__sum']
|
context['tot1'] = liste.aggregate(Sum(F('sem1')))['sem1__sum']
|
||||||
context['sem2'] = liste.exclude(sem2=0)
|
context['sem2'] = liste.exclude(sem2=0)
|
||||||
|
|
@ -307,37 +165,17 @@ def get_context(context):
|
||||||
context['sem6'] = liste.exclude(sem6=0)
|
context['sem6'] = liste.exclude(sem6=0)
|
||||||
context['tot6'] = liste.aggregate(Sum(F('sem6')))['sem6__sum']
|
context['tot6'] = liste.aggregate(Sum(F('sem6')))['sem6__sum']
|
||||||
|
|
||||||
context['tot'] = context['tot1'] + context['tot2'] + context['tot3'] + \
|
context['tot'] = context['tot1'] + context['tot2'] + context['tot3'] + context['tot4'] \
|
||||||
context['tot4'] + context['tot5'] + context['tot6']
|
+ context['tot5'] + context['tot6']
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class PeriodeView(TemplateView):
|
class PeriodeView(TemplateView):
|
||||||
template_name = 'cms/periodes.html'
|
template_name = 'cms/periodes.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = TemplateView.get_context_data(self, **kwargs)
|
context = TemplateView.get_context_data(self, **kwargs)
|
||||||
return get_context(context)
|
return get_context(context)
|
||||||
|
|
||||||
|
|
||||||
class PeriodePDFView(TemplateView):
|
|
||||||
|
|
||||||
def render_to_response(self, context, **response_kwargs):
|
|
||||||
context = get_context(context)
|
|
||||||
filename = os.path.join(settings.MEDIA_ROOT, 'periode.pdf')
|
|
||||||
pdf = PeriodPDF(filename)
|
|
||||||
for semestre_id in range(1, 7):
|
|
||||||
modules = context['sem{0}'.format(str(semestre_id))]
|
|
||||||
total = context['tot{0}'.format(str(semestre_id))]
|
|
||||||
pdf.produce_half_year(semestre_id, modules, total)
|
|
||||||
pdf.print_total(context['tot'])
|
|
||||||
pdf.canv.save()
|
|
||||||
|
|
||||||
with open(filename, mode='rb') as fh:
|
|
||||||
response = HttpResponse(fh.read(), content_type='application/pdf')
|
|
||||||
response['Content-Disposition'] = 'attachment; filename="{0}"'.format(filename)
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
class CompetenceListView(ListView):
|
class CompetenceListView(ListView):
|
||||||
|
|
@ -355,54 +193,3 @@ class TravailPersoListView(ListView):
|
||||||
context['total_presentiel'] = Module.objects.aggregate((Sum('periode_presentiel')))['periode_presentiel__sum']
|
context['total_presentiel'] = Module.objects.aggregate((Sum('periode_presentiel')))['periode_presentiel__sum']
|
||||||
context['total_pratique'] = Module.objects.aggregate((Sum('pratique_prof')))['pratique_prof__sum']
|
context['total_pratique'] = Module.objects.aggregate((Sum('pratique_prof')))['pratique_prof__sum']
|
||||||
return get_context(context)
|
return get_context(context)
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
class AddDocument(TemplateView):
|
|
||||||
template_name = 'cms/upload.html'
|
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
form = DocumentForm(request.POST, request.FILES)
|
|
||||||
if form.is_valid():
|
|
||||||
newdoc = Document(docfile = request.FILES['docfile'])
|
|
||||||
newdoc.save()
|
|
||||||
|
|
||||||
return HttpResponseRedirect('')
|
|
||||||
|
|
||||||
def get(self, request):
|
|
||||||
form = DocumentForm()
|
|
||||||
return render (request, 'cms/upload.html', {'form': form})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def AddDoc(request):
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = DocumentForm(request.POST, request.FILES)
|
|
||||||
if form.is_valid():
|
|
||||||
newdoc = Document(docfile = request.FILES['docfile'])
|
|
||||||
newdoc.save()
|
|
||||||
return HttpResponseRedirect('')
|
|
||||||
else:
|
|
||||||
form = DocumentForm()
|
|
||||||
|
|
||||||
documents = Document.objects.all()
|
|
||||||
return render (request, 'cms/upload.html', {'documents': documents,'form': form})
|
|
||||||
|
|
||||||
|
|
||||||
def Download(request, file_name):
|
|
||||||
f = os.path.join(settings.MEDIA_ROOT, file_name)
|
|
||||||
response = HttpResponse(content_type='application/pdf')
|
|
||||||
response['Content-Disposition'] = 'attachment; filename={0}'.format(file_name)
|
|
||||||
response['Content-Length'] = os.stat(f).st_size
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
def pdf_view(request):
|
|
||||||
with open(settings.MEDIA_ROOT + 'media/EDS_Calendrier_2017.pdf', 'r') as pdf:
|
|
||||||
response = HttpResponse(pdf.read().decode('latin-1') , content_type='application/pdf')
|
|
||||||
response['Content-Disposition'] = 'inline;filename=some_file.pdf'
|
|
||||||
return response
|
|
||||||
pdf.closed
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ print(BASE_DIR)
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = ['eds.webzos.net', 'localhost']
|
ALLOWED_HOSTS = ['eds.webzos.net', 'localhost', '127.0.0.1']
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
@ -37,6 +37,7 @@ INSTALLED_APPS = [
|
||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
'debug_toolbar',
|
||||||
'chartjs',
|
'chartjs',
|
||||||
'tinymce',
|
'tinymce',
|
||||||
'cms',
|
'cms',
|
||||||
|
|
@ -51,6 +52,7 @@ MIDDLEWARE = [
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'common.urls'
|
ROOT_URLCONF = 'common.urls'
|
||||||
|
|
@ -92,6 +94,22 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG_TOOLBAR_PANELS = [
|
||||||
|
'debug_toolbar.panels.versions.VersionsPanel',
|
||||||
|
'debug_toolbar.panels.timer.TimerPanel',
|
||||||
|
'debug_toolbar.panels.settings.SettingsPanel',
|
||||||
|
'debug_toolbar.panels.headers.HeadersPanel',
|
||||||
|
'debug_toolbar.panels.request.RequestPanel',
|
||||||
|
'debug_toolbar.panels.sql.SQLPanel',
|
||||||
|
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
|
||||||
|
'debug_toolbar.panels.templates.TemplatesPanel',
|
||||||
|
'debug_toolbar.panels.cache.CachePanel',
|
||||||
|
'debug_toolbar.panels.signals.SignalsPanel',
|
||||||
|
'debug_toolbar.panels.logging.LoggingPanel',
|
||||||
|
'debug_toolbar.panels.redirects.RedirectsPanel',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
||||||
|
|
||||||
|
|
@ -115,6 +133,7 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
|
||||||
|
|
||||||
|
"""
|
||||||
STUDENT_IMPORT_MAPPING = {
|
STUDENT_IMPORT_MAPPING = {
|
||||||
'Num élève': 'id_ext',
|
'Num élève': 'id_ext',
|
||||||
'Nom élève': 'nom',
|
'Nom élève': 'nom',
|
||||||
|
|
@ -127,6 +146,7 @@ STUDENT_IMPORT_MAPPING = {
|
||||||
'Date nais. élève': 'date_naissance',
|
'Date nais. élève': 'date_naissance',
|
||||||
'Classe': 'klasse',
|
'Classe': 'klasse',
|
||||||
}
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
DOMAINE_COULEURS = {
|
DOMAINE_COULEURS = {
|
||||||
'D1': '#fcaf3e',
|
'D1': '#fcaf3e',
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ from cms import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.HomeView.as_view(), name='home'),
|
url(r'^$', views.HomeView.as_view(), name='home'),
|
||||||
url(r'^plan_pdf/$', views.HomePDFView.as_view(), name='plan-pdf'),
|
# url(r'^plan_pdf/$', views.HomePDFView.as_view(), name='plan-pdf'),
|
||||||
|
url(r'^plan_pdf/$', views.print_plan_formation, name='plan-pdf'),
|
||||||
url(r'^admin/', admin.site.urls),
|
url(r'^admin/', admin.site.urls),
|
||||||
url(r'^domaine/(?P<pk>\d+)$', views.DomaineDetailView.as_view(), name='domaine-detail'),
|
url(r'^domaine/(?P<pk>\d+)$', views.DomaineDetailView.as_view(), name='domaine-detail'),
|
||||||
url(r'^domaines/$', views.DomaineListView.as_view(), name='domaine-list'),
|
url(r'^domaines/$', views.DomaineListView.as_view(), name='domaine-list'),
|
||||||
|
|
@ -31,14 +32,16 @@ urlpatterns = [
|
||||||
url(r'^module/(?P<pk>\d+)$', views.ModuleDetailView.as_view(), name='module-detail'),
|
url(r'^module/(?P<pk>\d+)$', views.ModuleDetailView.as_view(), name='module-detail'),
|
||||||
url(r'^modules/$', views.ModuleListView.as_view(), name='module-list'),
|
url(r'^modules/$', views.ModuleListView.as_view(), name='module-list'),
|
||||||
url(r'^periodes$', views.PeriodeView.as_view(), name='periodes'),
|
url(r'^periodes$', views.PeriodeView.as_view(), name='periodes'),
|
||||||
url(r'^periodes_pdf$', views.PeriodePDFView.as_view(), name='periodes-pdf'),
|
# url(r'^periodes_pdf$', views.PeriodePDFView.as_view(), name='periodes-pdf'),
|
||||||
|
url(r'^periodes_pdf$', views.print_periode_formation, name='periodes-pdf'),
|
||||||
url(r'^evaluation/$', views.EvaluationView.as_view(), name='evaluation'),
|
url(r'^evaluation/$', views.EvaluationView.as_view(), name='evaluation'),
|
||||||
url(r'^competences/$', views.CompetenceListView.as_view(), name='competences'),
|
url(r'^competences/$', views.CompetenceListView.as_view(), name='competences'),
|
||||||
url(r'^travail/$', views.TravailPersoListView.as_view(), name='travail'),
|
url(r'^travail/$', views.TravailPersoListView.as_view(), name='travail'),
|
||||||
# url(r'^upload/$', views.AddDocument.as_view(), name='upload'),
|
# url(r'^upload/$', views.AddDocument.as_view(), name='upload'),
|
||||||
# url(r'^download/(?P<file_name>.+)$', views.Download, name='download'),
|
# url(r'^download/(?P<file_name>.+)$', views.Download, name='download'),
|
||||||
# url(r'^calendrier/$', views.pdf_view, name='pdf-view'),
|
# url(r'^calendrier/$', views.pdf_view, name='pdf-view'),
|
||||||
url(r'^module_pdf/(?P<pk>\d+)$', views.ModulePDF.as_view(), name='module-pdf'),
|
url(r'^module_pdf/(?P<pk>\d+)$', views.print_module_pdf, name='module-pdf'),
|
||||||
|
# url(r'^module_pdf/(?P<pk>\d+)$', views.ModulePDF.as_view(), name='module-pdf'),
|
||||||
url(r'^documents/$', views.DocumentListView.as_view(), name='document-list'),
|
url(r'^documents/$', views.DocumentListView.as_view(), name='document-list'),
|
||||||
url(r'^document/(?P<pk>\d+)$', views.DocumentDetailView.as_view(), name='document-detail'),
|
url(r'^document/(?P<pk>\d+)$', views.DocumentDetailView.as_view(), name='document-detail'),
|
||||||
url(r'^upload/(?P<pk>\d+)$', views.UploadDetailView.as_view(), name='upload-detail'),
|
url(r'^upload/(?P<pk>\d+)$', views.UploadDetailView.as_view(), name='upload-detail'),
|
||||||
|
|
@ -47,3 +50,9 @@ urlpatterns = [
|
||||||
url(r'^tinymce/', include('tinymce.urls'), name='tinymce-js'),
|
url(r'^tinymce/', include('tinymce.urls'), name='tinymce-js'),
|
||||||
|
|
||||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
import debug_toolbar
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^__debug__/', include(debug_toolbar.urls)),
|
||||||
|
] + urlpatterns
|
||||||
BIN
media/logo_EPC.png
Normal file
BIN
media/logo_EPC.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
BIN
media/logo_ESNE.png
Normal file
BIN
media/logo_ESNE.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
|
|
@ -23,7 +23,7 @@ endobj
|
||||||
<< /Outlines 10 0 R /PageMode /UseNone /Pages 8 0 R /Type /Catalog >>
|
<< /Outlines 10 0 R /PageMode /UseNone /Pages 8 0 R /Type /Catalog >>
|
||||||
endobj
|
endobj
|
||||||
7 0 obj
|
7 0 obj
|
||||||
<< /Author (anonymous) /CreationDate (D:20170814074017-01'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20170814074017-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
<< /Author (anonymous) /CreationDate (D:20170816142811-01'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20170816142811-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
||||||
/Subject (unspecified) /Title (untitled) /Trapped /False >>
|
/Subject (unspecified) /Title (untitled) /Trapped /False >>
|
||||||
endobj
|
endobj
|
||||||
8 0 obj
|
8 0 obj
|
||||||
|
|
@ -243,7 +243,7 @@ xref
|
||||||
trailer
|
trailer
|
||||||
<< /ID
|
<< /ID
|
||||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
||||||
[(\353\211\003\306uO\376\265\357\030\317\244\200\211\306w) (\353\211\003\306uO\376\265\357\030\317\244\200\211\306w)]
|
[(\016b\032\207$\265\370\007t_\301\346\373~\373\007) (\016b\032\207$\265\370\007t_\301\346\373~\373\007)]
|
||||||
/Info 7 0 R /Root 6 0 R /Size 11 >>
|
/Info 7 0 R /Root 6 0 R /Size 11 >>
|
||||||
startxref
|
startxref
|
||||||
98675
|
98675
|
||||||
|
|
|
||||||
53
periode_formation.pdf
Normal file
53
periode_formation.pdf
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
%PDF-1.4
|
||||||
|
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
||||||
|
1 0 obj
|
||||||
|
<< /F1 2 0 R /F2 3 0 R >>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<< /Contents 8 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 7 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||||
|
/Type /Page >>
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<< /Outlines 9 0 R /PageMode /UseNone /Pages 7 0 R /Type /Catalog >>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
<< /Author (anonymous) /CreationDate (D:20171030142827-01'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20171030142827-01'00') /Producer (ReportLab PDF Library - www.reportlab.com)
|
||||||
|
/Subject (unspecified) /Title (untitled) /Trapped /False >>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<< /Count 1 /Kids [ 4 0 R ] /Type /Pages >>
|
||||||
|
endobj
|
||||||
|
8 0 obj
|
||||||
|
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1267 >>
|
||||||
|
stream
|
||||||
|
Gb!#\?*g"Y&:O;3s22Psm=U:LKV<<uHCL>JD(!Hu@pW+cqiUtJpi)CGh\?DE&75Ric"-0LN6UdQ[!VN5RY$;Jg0WeJi3tlInco?@@"/=%$&AIBh!MS?*(3&DLd`#&84aXf+Y_&pLdDS.jFdgDV1OKik/2@0X]lj/^^GN$1a&%3*F`hD?Me5Xg2:(N#1RG9=HA/CpC77t5)"ChcQ?,`WYuK5:U#<Zqk(oidYJL\&>Q^B^'B^0oQ7^W8Nc9^GY-`43mi3V#6j9Y4UE&?i>Ym7(gKB*i]\"B6heo;*:'\fV]>GrfC7'%o[(O4G]Wsh(Xk@U?+11^-cU:G/tcrUTAm5WE*Fq/lX1W"7,;_pLAiIA"&qu$Ptmo)?lg\%K[-]*39?WR;1)4TV2cW4'G=^G6#j$`)H/AE^q,'0/p4:*j4-OYPu,T84YIV-[@[ZfK(WRim1/<XbA>aI3Zj`n6_'HUJ""RXSlK]9RG3dWYNUN@O9&hlg$MIbib`E9qPJ](i):mV>sr?J,Ih6RKCJ\O7e[>W)9n\1[MEt/-"EI(mO<p(Su<XX1JVIAP@WVlP0H`$0t5dTDEWBMg18Ej%umn"=ds2\mi,a7eYI=#j/"29R`nBKCH9(GbDJ4f#1mn\V"2sEG&-8#PkAkh;LGXu*[dAgE'Pb_*K]M0O"Bo0%sY<D*a'2>*=]q*1@]$K-JqBACVdq-1A0Z'>*bO=8^X+hWYbD'$rA9&^YEjD*DHo8chr,i6"s6(;R6,*:m(Q)733YGkT!T6KJHVC27$I["'O3ieG19P)N.]=8q]W9QE`Tn^'cn^GA#`+@kJJZ<JBLXZg+khF[=r9`T3XjR4T/EXHJm@cW#@Bb0d6[nmF`CVX+X+a9Lp-Sn6n4lp#fa6#HS3bi%kgc!F4X/t22)@We(VCGu2FRf08<O9SIVDMg?W9Td0,A5+\G=se,uZ-L9M/RM@gQ;R0:e/@R^)T^??1$=nMmr-a@\r*bbMNr855<@og.XNS"k=>MhJ[/2m&N'0!1&-XZK.f.ZlNc=ZXO&%hfq,rUVP_qTc>K_l@us"/DlL1d!\4[%cROY`l$&@pP,@Z[r>l<h`^AS4)*!uIk=TkhC0H>_mJHRgqU%tR-5m-L>N`ChouS4uCHpW)ghmJmq>W8T04=NC;/&GMdT_\,p;"XbCHtu"X48TG0E='A+-V)LaB9>.Cp;$#0;6`P<43Z%F!+k3r][r&*fY/EGpETRR2GR-?bp!sipspYm<(#0nNq`EBR.)reC%b[K'h]-@$pC\~>endstream
|
||||||
|
endobj
|
||||||
|
9 0 obj
|
||||||
|
<< /Count 0 /Type /Outlines >>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 10
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000075 00000 n
|
||||||
|
0000000119 00000 n
|
||||||
|
0000000229 00000 n
|
||||||
|
0000000344 00000 n
|
||||||
|
0000000551 00000 n
|
||||||
|
0000000638 00000 n
|
||||||
|
0000000938 00000 n
|
||||||
|
0000001000 00000 n
|
||||||
|
0000002363 00000 n
|
||||||
|
trailer
|
||||||
|
<< /ID
|
||||||
|
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
||||||
|
[(\334E\217:\330\241\013\212ho\363\037w`p0) (\334E\217:\330\241\013\212ho\363\037w`p0)]
|
||||||
|
/Info 6 0 R /Root 5 0 R /Size 10 >>
|
||||||
|
startxref
|
||||||
|
2412
|
||||||
|
%%EOF
|
||||||
|
|
@ -156,7 +156,7 @@ font-size:105%;
|
||||||
|
|
||||||
.m {
|
.m {
|
||||||
border:1px solid black;
|
border:1px solid black;
|
||||||
font-size:105%;
|
font-size:105%;
|
||||||
text-align:center;
|
text-align:center;
|
||||||
vertical-align:middle;
|
vertical-align:middle;
|
||||||
height:20px;
|
height:20px;
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,21 @@
|
||||||
<html lang="{{ LANGUAGE_CODE|default:"fr" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
|
<html lang="{{ LANGUAGE_CODE|default:"fr" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
|
||||||
<head>
|
<head>
|
||||||
<title>{% block title %}{% endblock %}</title>
|
<title>{% block title %}{% endblock %}</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "css/main.css" %}" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/base.css" %}" />
|
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/base.css' %}" />
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />
|
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/dashboard.css' %}" />
|
||||||
<script type="text/javascript" src="{% static "js/tiny_mce/tiny_mce.js" %}"></script>
|
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}" />
|
||||||
|
<script type="text/javascript" src="{% static 'js/tiny_mce/tiny_mce.js' %}"></script>
|
||||||
<script src="{% static 'js/jquery.js' %}"></script>
|
<script src="{% static 'js/jquery.js' %}"></script>
|
||||||
{% block extrastyle %}<link rel="stylesheet" type="text/css" href="{% static "css/main.css" %}" />{% endblock %}
|
{% block extrastyle %}{% endblock %}
|
||||||
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}" />{% endif %}
|
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static 'admin/css/rtl.css' %}{% endblock %}" />{% endif %}
|
||||||
{% block extrahead %}{% endblock %}
|
{% block extrahead %}{% endblock %}
|
||||||
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
|
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}dashboard{% endblock %}"
|
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}dashboard{% endblock %}"
|
||||||
data-admin-utc-offset="{% now "Z" %}">
|
data-admin-utc-offset="{% now 'Z' %}">
|
||||||
|
|
||||||
<!-- Container -->
|
<!-- Container -->
|
||||||
<div id="container">
|
<div id="container">
|
||||||
|
|
@ -65,7 +66,7 @@
|
||||||
{% block messages %}
|
{% block messages %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
<ul class="messagelist">{% for message in messages %}
|
<ul class="messagelist">{% for message in messages %}
|
||||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
|
<li {% if message.tags %} class="{{ message.tags }}" {% endif %} >{{ message|capfirst }}</li>
|
||||||
{% endfor %}</ul>
|
{% endfor %}</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock messages %}
|
{% endblock messages %}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue