1 # -*- coding: utf-8 -*- |
|
2 |
|
3 from django.conf import settings |
|
4 from django.contrib.auth.models import User |
|
5 from django.db import models |
|
6 from hdabo.utils import Property, normalize |
|
7 import datetime |
|
8 |
|
9 |
|
10 |
|
11 class SortedModelManager(models.Manager): |
|
12 use_for_related_fields = True |
|
13 def get_query_set(self): |
|
14 qs = super(SortedModelManager, self).get_query_set() |
|
15 if getattr(self, 'through', None) is not None and getattr(self.through, 'Meta', None) is not None and getattr(self.through.Meta, 'ordering', None) is not None: |
|
16 qs = qs.order_by(*[self.through._meta.db_table + "." + f for f in self.through.Meta.ordering]) |
|
17 return qs |
|
18 |
|
19 |
|
20 class Organisation(models.Model): |
|
21 hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False) |
|
22 name = models.CharField(max_length=512, unique=False, blank=False, null=False) |
|
23 location = models.CharField(max_length=512, unique=False, blank=True, null=True) |
|
24 website = models.CharField(max_length=2048, unique=False, blank=True, null=True) |
|
25 |
|
26 class Author(models.Model): |
|
27 hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False) |
|
28 lastname = models.CharField(max_length=512, unique=False, blank=True, null=True) |
|
29 firstname = models.CharField(max_length=512, unique=False, blank=True, null=True) |
|
30 |
|
31 class TimePeriod(models.Model): |
|
32 TIME_PERIOD_CHOICES = ( |
|
33 (1, u'Primaire'), |
|
34 (2, u'Collège'), |
|
35 (3, u'Lycée'), |
|
36 ) |
|
37 TIME_PERIOD_DICT = { |
|
38 u'Primaire': 1, |
|
39 u'Collège': 2, |
|
40 u'Lycée': 3, |
|
41 } |
|
42 label = models.CharField(max_length=512, unique=False, blank=False, null=False) |
|
43 school_period = models.IntegerField(choices=TIME_PERIOD_CHOICES) |
|
44 |
|
45 objects = SortedModelManager() |
|
46 |
|
47 class Meta: |
|
48 unique_together = ("label", "school_period") |
|
49 |
|
50 def __unicode__(self): |
|
51 return unicode(self.label) |
|
52 |
|
53 class Domain(models.Model): |
|
54 DOMAIN_PERIOD_CHOICES = ( |
|
55 (0, u'Global'), |
|
56 (1, u'Primaire'), |
|
57 (2, u'Collège'), |
|
58 (3, u'Lycée'), |
|
59 ) |
|
60 DOMAIN_PERIOD_DICT = { |
|
61 u'Global': 0, |
|
62 u'Primaire': 1, |
|
63 u'Collège': 2, |
|
64 u'Lycée': 3, |
|
65 } |
|
66 label = models.CharField(max_length=512, unique=False, blank=False, null=False) |
|
67 school_period = models.IntegerField(choices=DOMAIN_PERIOD_CHOICES) |
|
68 |
|
69 objects = SortedModelManager() |
|
70 |
|
71 class Meta: |
|
72 unique_together = ("label", "school_period") |
|
73 |
|
74 def __unicode__(self): |
|
75 return unicode(self.label) |
|
76 |
|
77 |
|
78 class DocumentFormat(models.Model): |
|
79 label = models.CharField(max_length=512, unique=True, blank=False, null=False) |
|
80 |
|
81 def __unicode__(self): |
|
82 return unicode(self.label) |
|
83 |
|
84 class TagCategory(models.Model): |
|
85 label = models.CharField(max_length=512, unique=True, blank=False, null=False) |
|
86 |
|
87 def __unicode__(self): |
|
88 return unicode(self.label) |
|
89 |
|
90 class Meta: |
|
91 verbose_name_plural = "TagCategories" |
|
92 |
|
93 class Tag(models.Model): |
|
94 TAG_URL_STATUS_CHOICES = ( |
|
95 (0, "null_result"), |
|
96 (1, "redirection"), |
|
97 (2, "homonyme"), |
|
98 (3, "match"), |
|
99 (4, "unsematized"), |
|
100 ) |
|
101 |
|
102 TAG_URL_STATUS_DICT = { |
|
103 "null_result":0, |
|
104 "redirection":1, |
|
105 "homonyme":2, |
|
106 "match":3, |
|
107 "unsemantized":4, |
|
108 } |
|
109 |
|
110 label = models.CharField(max_length=1024, unique=False, blank=False, null=False, db_index=True) |
|
111 alternative_label = models.CharField(max_length=1024, unique=False, blank=True, null=True) |
|
112 normalized_label = models.CharField(max_length=1024, unique=False, blank=False, null=False, db_index=True, editable=False) |
|
113 created_at = models.DateTimeField(auto_now_add=True) |
|
114 original_label = models.CharField(max_length=1024, unique=False, blank=False, null=False, editable=False) |
|
115 alias = models.CharField(max_length=1024, unique=False, blank=True, null=True) |
|
116 category = models.ForeignKey(TagCategory, null=True, blank=True) |
|
117 wikipedia_url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True, db_index=True) |
|
118 wikipedia_pageid = models.BigIntegerField(unique=False, blank=True, null=True, db_index=True) |
|
119 alternative_wikipedia_url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True, db_index=True) |
|
120 alternative_wikipedia_pageid = models.BigIntegerField(unique=False, blank=True, null=True, db_index=True) |
|
121 url_status = models.IntegerField(choices=TAG_URL_STATUS_CHOICES, blank=True, null=True, default=None, db_index=True) |
|
122 dbpedia_uri = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True, db_index=True) |
|
123 popularity = models.IntegerField(blank=False, null=False, default=0, db_index=True) |
|
124 |
|
125 @Property |
|
126 def url_status_text(): #@NoSelf |
|
127 def fget(self): |
|
128 return self.TAG_URL_STATUS_CHOICES[self.url_status][1] |
|
129 |
|
130 return locals() |
|
131 |
|
132 def save(self, *args, **kwargs): |
|
133 self.normalized_label = normalize(self.label) |
|
134 super(Tag, self).save(*args, **kwargs) |
|
135 |
|
136 class Meta: |
|
137 unique_together = (('label', 'original_label', 'url_status'),) |
|
138 |
|
139 class Location(models.Model): |
|
140 name = models.CharField(max_length=512, unique=False, blank=False, null=False) |
|
141 insee = models.CharField(max_length=5, unique=True, blank=False, null=False) |
|
142 |
|
143 def __unicode__(self): |
|
144 return unicode("%s : %s" % (self.name, self.insee)) |
|
145 |
|
146 |
|
147 def generate_m2m_setter(m2m_field_name): |
|
148 |
|
149 def set_m2m_field(self, list): |
|
150 |
|
151 m2m_manager = getattr(self, m2m_field_name) |
|
152 m2m_manager.clear() |
|
153 |
|
154 through_klass = set_m2m_field.cache.get('through_klass', None) |
|
155 if through_klass is None: |
|
156 field = getattr(self.__class__, m2m_field_name) |
|
157 through_klass = field.through |
|
158 set_m2m_field.cache['through_klass'] = through_klass |
|
159 for f in through_klass._meta.fields: |
|
160 if isinstance(f, models.ForeignKey) and f.name != "datasheet": |
|
161 set_m2m_field.cache['target_obj_field_name'] = f.name |
|
162 break |
|
163 target_obj_field_name = set_m2m_field.cache['target_obj_field_name'] |
|
164 |
|
165 for i, obj in enumerate(list): |
|
166 kwargs = { |
|
167 'datasheet': self, |
|
168 'sort_value' : i, |
|
169 target_obj_field_name: obj |
|
170 } |
|
171 new_rel = through_klass(**kwargs) |
|
172 new_rel.save() |
|
173 set_m2m_field.cache = {} |
|
174 |
|
175 return set_m2m_field |
|
176 |
|
177 |
|
178 class Datasheet(models.Model): |
|
179 hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False) |
|
180 author = models.ForeignKey(Author, null=True, blank=True, serialize=False) |
|
181 organisation = models.ForeignKey(Organisation, serialize=False, null=True) |
|
182 title = models.CharField(max_length=2048, unique=False, blank=False, null=False, serialize=False) |
|
183 description = models.TextField(blank=True, null=True, serialize=False) |
|
184 url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True, serialize=False) |
|
185 domains = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Global']}, related_name="datasheets", through="Datasheet_domains", serialize=False) |
|
186 primary_periods = models.ManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Primaire']}, related_name="primary_periods_datasheets", through="Datasheet_primary_periods", serialize=False) |
|
187 college_periods = models.ManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Collège']}, related_name="college_periods_datasheets", through="Datasheet_college_periods", serialize=False) |
|
188 highschool_periods = models.ManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Lycée']}, related_name="highschool_periods_datasheets", through="Datasheet_highschool_periods", serialize=False) |
|
189 primary_themes = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Primaire']}, related_name="primary_themes_datasheets", through="Datasheet_primary_themes", serialize=False) |
|
190 college_themes = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Collège']}, related_name="college_themes_datasheets", through="Datasheet_college_themes", serialize=False) |
|
191 highschool_themes = models.ManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Lycée']}, related_name="highschool_themes_datasheets", through="Datasheet_highschool_themes", serialize=False) |
|
192 town = models.ForeignKey(Location, null=True, blank=True, serialize=False) |
|
193 format = models.ForeignKey(DocumentFormat, null=True, blank=True, serialize=False) |
|
194 original_creation_date = models.DateField(serialize=False) |
|
195 original_modification_date = models.DateField(serialize=False) |
|
196 modification_datetime = models.DateTimeField(auto_now=True, serialize=False) |
|
197 validation_date = models.DateTimeField(null=True, blank=True, serialize=False) |
|
198 validated = models.BooleanField(default=False, db_index=True) |
|
199 validator = models.ForeignKey(User, null=True, blank=True, serialize=False) |
|
200 manual_order = models.BooleanField(default=False, db_index=True, serialize=False) |
|
201 tags = models.ManyToManyField(Tag, through='TaggedSheet', serialize=False) |
|
202 |
|
203 def natural_key(self): |
|
204 return self.hda_id |
|
205 |
|
206 def validate(self, user): |
|
207 self.validation_date = datetime.datetime.now() |
|
208 self.validated = True |
|
209 self.validator = user |
|
210 self.save() |
|
211 |
|
212 def unvalidate(self): |
|
213 self.validation_date = datetime.datetime.min |
|
214 self.validated = False |
|
215 self.validator = None |
|
216 self.save() |
|
217 |
|
218 |
|
219 set_domains = generate_m2m_setter("domains") |
|
220 |
|
221 @Property |
|
222 def domains_list(): #@NoSelf |
|
223 def fget(self): |
|
224 return [d.label for d in self.domains.all()] |
|
225 |
|
226 return locals() |
|
227 |
|
228 @Property |
|
229 def domains_text(): #@NoSelf |
|
230 def fget(self): |
|
231 return "; ".join(self.domains_list) |
|
232 |
|
233 return locals() |
|
234 |
|
235 |
|
236 set_primary_periods = generate_m2m_setter("primary_periods") |
|
237 |
|
238 @Property |
|
239 def primary_periods_list(): #@NoSelf |
|
240 def fget(self): |
|
241 return [d.label for d in self.primary_periods.all()] |
|
242 |
|
243 return locals() |
|
244 |
|
245 |
|
246 @Property |
|
247 def primary_periods_text(): #@NoSelf |
|
248 def fget(self): |
|
249 return "; ".join(self.primary_periods_list) |
|
250 |
|
251 return locals() |
|
252 |
|
253 set_college_periods = generate_m2m_setter("college_periods") |
|
254 |
|
255 @Property |
|
256 def college_periods_list(): #@NoSelf |
|
257 def fget(self): |
|
258 return [d.label for d in self.college_periods.all()] |
|
259 |
|
260 return locals() |
|
261 |
|
262 @Property |
|
263 def college_periods_text(): #@NoSelf |
|
264 def fget(self): |
|
265 return "; ".join(self.college_periods_list) |
|
266 |
|
267 return locals() |
|
268 |
|
269 set_highschool_periods = generate_m2m_setter("highschool_periods") |
|
270 |
|
271 @Property |
|
272 def highschool_periods_list(): #@NoSelf |
|
273 def fget(self): |
|
274 return [d.label for d in self.highschool_periods.all()] |
|
275 |
|
276 return locals() |
|
277 |
|
278 @Property |
|
279 def highschool_periods_text(): #@NoSelf |
|
280 def fget(self): |
|
281 return "; ".join(self.highschool_periods_list) |
|
282 |
|
283 return locals() |
|
284 |
|
285 set_primary_themes = generate_m2m_setter("primary_themes") |
|
286 |
|
287 @Property |
|
288 def primary_themes_list(): #@NoSelf |
|
289 def fget(self): |
|
290 return [d.label for d in self.primary_themes.all()] |
|
291 |
|
292 return locals() |
|
293 |
|
294 |
|
295 @Property |
|
296 def primary_themes_text(): #@NoSelf |
|
297 def fget(self): |
|
298 return "; ".join(self.primary_themes_list) |
|
299 |
|
300 return locals() |
|
301 |
|
302 set_college_themes = generate_m2m_setter("college_themes") |
|
303 |
|
304 @Property |
|
305 def college_themes_list(): #@NoSelf |
|
306 def fget(self): |
|
307 return [d.label for d in self.college_themes.all()] |
|
308 |
|
309 return locals() |
|
310 |
|
311 @Property |
|
312 def college_themes_text(): #@NoSelf |
|
313 def fget(self): |
|
314 return "; ".join(self.college_themes_list) |
|
315 |
|
316 return locals() |
|
317 |
|
318 set_highschool_themes = generate_m2m_setter("highschool_themes") |
|
319 |
|
320 @Property |
|
321 def highschool_themes_list(): #@NoSelf |
|
322 def fget(self): |
|
323 return [d.label for d in self.highschool_themes.all()] |
|
324 |
|
325 return locals() |
|
326 |
|
327 @Property |
|
328 def highschool_themes_text(): #@NoSelf |
|
329 def fget(self): |
|
330 return "; ".join(self.highschool_themes_list) |
|
331 |
|
332 return locals() |
|
333 |
|
334 @Property |
|
335 def town_text(): #@NoSelf |
|
336 def fget(self): |
|
337 return self.town.name if self.town else "" |
|
338 |
|
339 return locals() |
|
340 |
|
341 @Property |
|
342 def tags_text(): #@NoSelf |
|
343 def fget(self): |
|
344 return "; ".join([t.label for t in self.tags.all()]) |
|
345 |
|
346 return locals() |
|
347 |
|
348 @models.permalink |
|
349 def get_absolute_url(self): |
|
350 return ('display_datasheet', (), { |
|
351 'ds_id': self.hda_id |
|
352 }) |
|
353 |
|
354 |
|
355 class TaggedSheet(models.Model): |
|
356 datasheet = models.ForeignKey(Datasheet) |
|
357 tag = models.ForeignKey(Tag) |
|
358 created_at = models.DateTimeField(auto_now_add=True) |
|
359 original_order = models.IntegerField(null=False, blank=False, default=0) |
|
360 order = models.IntegerField(null=False, blank=False, default=0, db_index=True) |
|
361 index_note = models.FloatField(null=False, blank=False, default=0.0, db_index=True) |
|
362 wikipedia_revision_id = models.BigIntegerField(unique=False, blank=True, null=True) |
|
363 |
|
364 @Property |
|
365 def wikipedia_verion_permalink(): #@NoSelf |
|
366 def fget(self): |
|
367 return settings.WIKIPEDIA_VERSION_PERMALINK_TEMPLATE % (unicode(self.wikipedia_revision_id)) |
|
368 |
|
369 return locals() |
|
370 |
|
371 |
|
372 class SortedDatasheetLink(models.Model): |
|
373 datasheet = models.ForeignKey(Datasheet, db_index=True, null=False, blank=False) |
|
374 sort_value = models.IntegerField(null=False, blank=False) |
|
375 |
|
376 class Meta: |
|
377 abstract = True |
|
378 ordering = ['sort_value'] |
|
379 |
|
380 |
|
381 class Datasheet_domains(SortedDatasheetLink): |
|
382 domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False) |
|
383 |
|
384 class Datasheet_highschool_periods(SortedDatasheetLink): |
|
385 timeperiod = models.ForeignKey(TimePeriod, db_index=True, null=False, blank=False) |
|
386 |
|
387 class Datasheet_highschool_themes(SortedDatasheetLink): |
|
388 domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False) |
|
389 |
|
390 class Datasheet_college_periods(SortedDatasheetLink): |
|
391 timeperiod = models.ForeignKey(TimePeriod, db_index=True, null=False, blank=False) |
|
392 |
|
393 class Datasheet_college_themes(SortedDatasheetLink): |
|
394 domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False) |
|
395 |
|
396 class Datasheet_primary_periods(SortedDatasheetLink): |
|
397 timeperiod = models.ForeignKey(TimePeriod, db_index=True, null=False, blank=False) |
|
398 |
|
399 class Datasheet_primary_themes(SortedDatasheetLink): |
|
400 domain = models.ForeignKey(Domain, db_index=True, null=False, blank=False) |
|
401 |
|
402 |
|
403 |
|
404 |
|