Commit | Line | Data |
---|---|---|
544b4522 | 1 | # -*- encoding: utf-8 -*- |
73309469 | 2 | import re, datetime |
544b4522 | 3 | from django import forms |
6cdb7d49 | 4 | from django import db |
7bbf600c | 5 | from django.db.models import Q |
73309469 | 6 | from django.db import models |
7 | from django.contrib.admin import widgets | |
0a77a7d6 | 8 | from datamaster_modeles.models import Thematique, Pays, Region |
c9cbc784 | 9 | from models import Evenement, Discipline, Record, Actualite |
0b72ebef | 10 | from savoirs.lib.recherche import build_search_regexp |
73309469 | 11 | from savoirs.admin import EvenementAdminForm |
60d2095f | 12 | import settings |
da44ce68 | 13 | |
7bbf600c EMS |
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): | |
0a8666f8 | 20 | super(SEPDateField, self).__init__(self, *args, **kwargs) |
7bbf600c EMS |
21 | |
22 | # La classe "date" active le datepicker dans sep.js | |
7bbf600c | 23 | # Nous recevons les dates en format français |
0a8666f8 | 24 | format = '%d/%m/%Y' |
25 | self.widget = forms.DateInput(attrs={'class': 'date'}, format=format) | |
26 | self.input_formats = [format,] | |
7bbf600c | 27 | |
da44ce68 | 28 | # Formulaires de recherche |
544b4522 | 29 | |
da44ce68 EMS |
30 | class RecordSearchForm(forms.Form): |
31 | """Formulaire de recherche pour les ressources.""" | |
32 | ||
6cdb7d49 EMS |
33 | class TypeChoices(object): |
34 | ||
35 | def __iter__(self): | |
36 | """Génère dynamiquement les choix possibles pour la recherche par type.""" | |
9113aa36 | 37 | yield ('', 'Tous') |
6cdb7d49 | 38 | cursor = db.connection.cursor() |
0e5d5bc9 EMS |
39 | cursor.execute("""SELECT DISTINCT TRIM(REPLACE(REPLACE(type, ', PeerReviewed', ''), ', NonPeerReviewed', '')) AS clean_type |
40 | FROM savoirs_record ORDER BY clean_type""") | |
6cdb7d49 | 41 | for result in cursor.fetchall(): |
0e5d5bc9 | 42 | type = result[0] |
6cdb7d49 EMS |
43 | if type: |
44 | yield (type, type) | |
6cdb7d49 EMS |
45 | TYPE_CHOICES = TypeChoices() |
46 | ||
0e5d5bc9 EMS |
47 | class PublisherChoices(object): |
48 | ||
49 | def __iter__(self): | |
50 | """Génère dynamiquement les choix possibles pour la recherche par éditeur.""" | |
9113aa36 | 51 | yield ('', 'Tous') |
0e5d5bc9 EMS |
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 | ||
da44ce68 | 60 | q = forms.CharField(required=False, label="Mots-clés") |
f12cc7fb EMS |
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") | |
9113aa36 EMS |
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') | |
0e5d5bc9 EMS |
66 | type = forms.ChoiceField(required=False, label="Type de document", choices=TYPE_CHOICES) |
67 | publisher = forms.ChoiceField(required=False, label="Éditeur", choices=PUBLISHER_CHOICES) | |
da44ce68 EMS |
68 | |
69 | def get_query_set(self): | |
70 | """Retourne l'ensemble des ressources qui correspondent aux valeurs | |
71 | entrées dans le formulaire.""" | |
f153be1b | 72 | records = Record.objects.validated() |
da44ce68 EMS |
73 | if self.is_valid(): |
74 | query = self.cleaned_data['q'] | |
75 | if query: | |
76 | records = records.search(query) | |
f12cc7fb EMS |
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) | |
9113aa36 EMS |
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) | |
6cdb7d49 EMS |
92 | type = self.cleaned_data['type'] |
93 | if type: | |
94 | records = records.filter(type__icontains=type) | |
0e5d5bc9 EMS |
95 | publisher = self.cleaned_data['publisher'] |
96 | if publisher: | |
97 | records = records.filter(publisher=publisher) | |
da44ce68 EMS |
98 | return records |
99 | ||
f61e4846 EMS |
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(): | |
0b72ebef | 104 | return build_search_regexp(self.cleaned_data['q']) |
f61e4846 | 105 | |
c9cbc784 EMS |
106 | class ActualiteSearchForm(forms.Form): |
107 | """Formulaire de recherche pour les actualités.""" | |
108 | ||
109 | q = forms.CharField(required=False, label="Mots-clés") | |
7bbf600c EMS |
110 | date_min = SEPDateField(required=False, label="Depuis le") |
111 | date_max = SEPDateField(required=False, label="Jusqu'au") | |
c9cbc784 EMS |
112 | |
113 | def get_query_set(self): | |
114 | """Retourne l'ensemble des actualités qui correspondent aux valeurs | |
115 | entrées dans le formulaire.""" | |
f153be1b | 116 | actualites = Actualite.objects.filter(visible=True) |
c9cbc784 EMS |
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: | |
c9cbc784 EMS |
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']) | |
4101cfc0 EMS |
134 | |
135 | class EvenementSearchForm(forms.Form): | |
b5e81cfb | 136 | """Formulaire de recherche pour les évènements.""" |
4101cfc0 EMS |
137 | |
138 | q = forms.CharField(required=False, label="Mots-clés") | |
7bbf600c EMS |
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") | |
4101cfc0 EMS |
145 | |
146 | def get_query_set(self): | |
b5e81cfb | 147 | """Retourne l'ensemble des évènements qui correspondent aux valeurs |
4101cfc0 EMS |
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) | |
7bbf600c EMS |
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) | |
4101cfc0 EMS |
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 | ||
da44ce68 | 177 | ### |
544b4522 | 178 | |
73309469 | 179 | class FrontEndSplitDateTime(widgets.AdminSplitDateTime): |
180 | class Media: | |
60d2095f | 181 | extend=False |
713e8613 | 182 | js = ("/jsi18n/", |
60d2095f | 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', ) | |
73309469 | 187 | css = {'all' : ('css/calendrier.css', )} |
188 | ||
189 | class EvenementForm(EvenementAdminForm): | |
190 | debut = forms.DateTimeField(widget=FrontEndSplitDateTime) | |
191 | fin = forms.DateTimeField(widget=FrontEndSplitDateTime) | |
192 | ||
92c7413b CR |
193 | class Meta: |
194 | model = Evenement | |
3a45eb64 | 195 | exclude = ('approuve', 'uid', 'regions') |
0a77a7d6 | 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): | |
264a3210 | 204 | regions = forms.ModelMultipleChoiceField(queryset=Region.objects.all()) |
0a77a7d6 | 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): | |
264a3210 | 211 | disciplines = forms.ModelMultipleChoiceField(queryset=Discipline.objects.all()) |
0a77a7d6 | 212 | |
213 | class ConfirmationForm(forms.Form): | |
214 | pass | |
215 |