Assigner les disciplines et régions en bloc dans l'admin
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / savoirs / forms.py
1 # -*- encoding: utf-8 -*-
2 import re, datetime
3 from django import forms
4 from django import db
5 from django.db.models import Q
6 from django.db import models
7 from django.contrib.admin import widgets
8 from datamaster_modeles.models import Thematique, Pays, Region
9 from models import Evenement, Discipline, Record, Actualite
10 from savoirs.lib.recherche import build_search_regexp
11 from savoirs.admin import EvenementAdminForm
12 import settings
13
14 # Modifications custom aux champs Django
15
16 class SEPDateField(forms.DateField):
17 """Un champ de date avec des valeurs par défaut un peu modifiées."""
18
19 def __init__(self, *args, **kwargs):
20 super(SEPDateField, self).__init__(self, *args, **kwargs)
21
22 # La classe "date" active le datepicker dans sep.js
23 # Nous recevons les dates en format français
24 format = '%d/%m/%Y'
25 self.widget = forms.DateInput(attrs={'class': 'date'}, format=format)
26 self.input_formats = [format,]
27
28 # Formulaires de recherche
29
30 class RecordSearchForm(forms.Form):
31 """Formulaire de recherche pour les ressources."""
32
33 class TypeChoices(object):
34
35 def __iter__(self):
36 """Génère dynamiquement les choix possibles pour la recherche par type."""
37 yield ('', 'Tous')
38 cursor = db.connection.cursor()
39 cursor.execute("""SELECT DISTINCT TRIM(REPLACE(REPLACE(type, ', PeerReviewed', ''), ', NonPeerReviewed', '')) AS clean_type
40 FROM savoirs_record ORDER BY clean_type""")
41 for result in cursor.fetchall():
42 type = result[0]
43 if type:
44 yield (type, type)
45 TYPE_CHOICES = TypeChoices()
46
47 class PublisherChoices(object):
48
49 def __iter__(self):
50 """Génère dynamiquement les choix possibles pour la recherche par éditeur."""
51 yield ('', 'Tous')
52 cursor = db.connection.cursor()
53 cursor.execute("SELECT DISTINCT publisher AS publisher FROM savoirs_record ORDER BY publisher")
54 for result in cursor.fetchall():
55 publisher = result[0]
56 if publisher not in ('', '-'):
57 yield (publisher, publisher)
58 PUBLISHER_CHOICES = PublisherChoices()
59
60 q = forms.CharField(required=False, label="Mots-clés")
61 auteur = forms.CharField(required=False, label="Auteur ou contributeur")
62 titre = forms.CharField(required=False, label="Titre")
63 sujet = forms.CharField(required=False, label="Sujet")
64 discipline = forms.ModelChoiceField(required=False, label="Discipline", queryset=Discipline.objects.all(), empty_label='Toutes')
65 region = forms.ModelChoiceField(required=False, label="Région", queryset=Region.objects.all(), empty_label='Toutes')
66 type = forms.ChoiceField(required=False, label="Type de document", choices=TYPE_CHOICES)
67 publisher = forms.ChoiceField(required=False, label="Éditeur", choices=PUBLISHER_CHOICES)
68
69 def get_query_set(self):
70 """Retourne l'ensemble des ressources qui correspondent aux valeurs
71 entrées dans le formulaire."""
72 records = Record.objects.validated()
73 if self.is_valid():
74 query = self.cleaned_data['q']
75 if query:
76 records = records.search(query)
77 auteur = self.cleaned_data['auteur']
78 if auteur:
79 records = records.search_auteur(auteur)
80 titre = self.cleaned_data['titre']
81 if titre:
82 records = records.search_titre(titre)
83 sujet = self.cleaned_data['sujet']
84 if sujet:
85 records = records.search_sujet(sujet)
86 discipline = self.cleaned_data['discipline']
87 if discipline:
88 records = records.filter(disciplines=discipline)
89 region = self.cleaned_data['region']
90 if region:
91 records = records.filter(regions=region)
92 type = self.cleaned_data['type']
93 if type:
94 records = records.filter(type__icontains=type)
95 publisher = self.cleaned_data['publisher']
96 if publisher:
97 records = records.filter(publisher=publisher)
98 return records
99
100 def get_search_regexp(self):
101 """Retourne une expression régulière compilée qui peut servir à
102 chercher les mot-clés recherchés dans un texte."""
103 if self.is_valid():
104 return build_search_regexp(self.cleaned_data['q'])
105
106 class ActualiteSearchForm(forms.Form):
107 """Formulaire de recherche pour les actualités."""
108
109 q = forms.CharField(required=False, label="Mots-clés")
110 date_min = SEPDateField(required=False, label="Depuis le")
111 date_max = SEPDateField(required=False, label="Jusqu'au")
112
113 def get_query_set(self):
114 """Retourne l'ensemble des actualités qui correspondent aux valeurs
115 entrées dans le formulaire."""
116 actualites = Actualite.objects.filter(visible=True)
117 if self.is_valid():
118 query = self.cleaned_data['q']
119 if query:
120 actualites = actualites.search(query)
121 date_min = self.cleaned_data['date_min']
122 if date_min:
123 actualites = actualites.filter(date__gte=date_min)
124 date_max = self.cleaned_data['date_max']
125 if date_max:
126 actualites = actualites.filter(date__lte=date_max)
127 return actualites
128
129 def get_search_regexp(self):
130 """Retourne une expression régulière compilée qui peut servir à
131 chercher les mot-clés recherchés dans un texte."""
132 if self.is_valid():
133 return build_search_regexp(self.cleaned_data['q'])
134
135 class EvenementSearchForm(forms.Form):
136 """Formulaire de recherche pour les évènements."""
137
138 q = forms.CharField(required=False, label="Mots-clés")
139 titre = forms.CharField(required=False, label="Intitulé")
140 type = forms.ChoiceField(required=False, choices=(('', 'Tous'),)+Evenement.TYPE_CHOICES)
141 discipline = forms.ModelChoiceField(queryset=Discipline.objects.all(),
142 required=False, label="Discipline", empty_label="Toutes")
143 date_min = SEPDateField(required=False, label="Depuis le")
144 date_max = SEPDateField(required=False, label="Jusqu'au")
145
146 def get_query_set(self):
147 """Retourne l'ensemble des évènements qui correspondent aux valeurs
148 entrées dans le formulaire."""
149 evenements = Evenement.objects.filter(approuve=True)
150 if self.is_valid():
151 query = self.cleaned_data['q']
152 if query:
153 evenements = evenements.search(query)
154 titre = self.cleaned_data['titre']
155 if titre:
156 evenements = evenements.search_titre(titre)
157 type = self.cleaned_data['type']
158 if type:
159 evenements = evenements.filter(type=type)
160 discipline = self.cleaned_data['discipline']
161 if discipline:
162 evenements = evenements.filter(Q(discipline=discipline) | Q(discipline_secondaire=discipline))
163 date_min = self.cleaned_data['date_min']
164 if date_min:
165 evenements = evenements.filter(debut__gte=date_min)
166 date_max = self.cleaned_data['date_max']
167 if date_max:
168 evenements = evenements.filter(debut__lte=date_max)
169 return evenements
170
171 def get_search_regexp(self):
172 """Retourne une expression régulière compilée qui peut servir à
173 chercher les mot-clés recherchés dans un texte."""
174 if self.is_valid():
175 return build_search_regexp(self.cleaned_data['q'])
176
177 ###
178
179 class FrontEndSplitDateTime(widgets.AdminSplitDateTime):
180 class Media:
181 extend=False
182 js = ("/jsi18n/",
183 settings.ADMIN_MEDIA_PREFIX + "js/core.js",
184 settings.ADMIN_MEDIA_PREFIX + "js/calendar.js",
185 settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js",
186 'js/calendrier.js', )
187 css = {'all' : ('css/calendrier.css', )}
188
189 class EvenementForm(EvenementAdminForm):
190 debut = forms.DateTimeField(widget=FrontEndSplitDateTime)
191 fin = forms.DateTimeField(widget=FrontEndSplitDateTime)
192
193 class Meta:
194 model = Evenement
195 exclude = ('approuve', 'uid', 'regions')
196
197 # Admin views pour les associations par lots
198
199 class PaysForm(forms.Form):
200 values = [(p.id, p.nom) for p in Pays.objects.all()]
201 pays = forms.MultipleChoiceField(choices=values)
202
203 class RegionsForm(forms.Form):
204 regions = forms.ModelMultipleChoiceField(queryset=Region.objects.all())
205
206 class ThematiquesForm(forms.Form):
207 values = [(t.id, t.nom) for t in Thematique.objects.all()]
208 thematiques = forms.MultipleChoiceField(choices=values)
209
210 class DisciplinesForm(forms.Form):
211 disciplines = forms.ModelMultipleChoiceField(queryset=Discipline.objects.all())
212
213 class ConfirmationForm(forms.Form):
214 pass
215