summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chimere/forms.py18
-rw-r--r--chimere/locale/fr/LC_MESSAGES/django.po256
-rw-r--r--chimere/migrations/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py241
-rw-r--r--chimere/models.py23
-rw-r--r--chimere/templates/chimere/edit.html31
-rw-r--r--chimere/views.py4
-rw-r--r--debian/control3
-rw-r--r--docs/install.rst4
-rw-r--r--docs/upgrade.rst5
-rw-r--r--requirements.txt1
10 files changed, 455 insertions, 131 deletions
diff --git a/chimere/forms.py b/chimere/forms.py
index e3486c0..d877a22 100644
--- a/chimere/forms.py
+++ b/chimere/forms.py
@@ -124,10 +124,11 @@ class MarkerAdminFormBase(forms.ModelForm):
"""
Custom initialization method in order to manage properties
"""
+ self.pms = [pm for pm in PropertyModel.objects.filter(available=True)]
if 'instance' in keys and keys['instance']:
instance = keys['instance']
property_dct = {}
- for pm in PropertyModel.objects.filter(available=True):
+ for pm in self.pms:
property = instance.getProperty(pm)
if property:
property_dct[pm.getNamedId()] = property.value
@@ -147,6 +148,8 @@ class MarkerAdminFormBase(forms.ModelForm):
def clean(self):
'''
Verify that a start date is provided when an end date is set
+ Verify the mandatory properties (to be check manualy because it depends
+ on the checked categories)
'''
if not settings.CHIMERE_DAYS_BEFORE_EVENT:
return self.cleaned_data
@@ -155,6 +158,19 @@ class MarkerAdminFormBase(forms.ModelForm):
msg = _(u"End date has been set with no start date")
self._errors["end_date"] = self.error_class([msg])
del self.cleaned_data['end_date']
+
+ for pm in self.pms:
+ if not pm.mandatory or self.cleaned_data[pm.getNamedId()]:
+ continue
+ pm_cats = pm.subcategories.all()
+ print self.cleaned_data['categories']
+ print pm_cats
+ if not pm_cats or \
+ [submited_cat for submited_cat in self.cleaned_data['categories']
+ if submited_cat in pm_cats]:
+ msg = _(u"This field is mandatory for the selected categories")
+ self._errors[pm.getNamedId()] = self.error_class([msg])
+ #raise forms.ValidationError()
return self.cleaned_data
def save(self, *args, **keys):
diff --git a/chimere/locale/fr/LC_MESSAGES/django.po b/chimere/locale/fr/LC_MESSAGES/django.po
index 5d4a250..4462ff1 100644
--- a/chimere/locale/fr/LC_MESSAGES/django.po
+++ b/chimere/locale/fr/LC_MESSAGES/django.po
@@ -7,18 +7,18 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.2\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-08-20 21:03+0200\n"
+"POT-Creation-Date: 2012-08-20 21:17+0200\n"
"PO-Revision-Date: 2010-03-20 20:00+0100\n"
"Last-Translator: Étienne Loks <etienne.loks@peacefrogs.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: __init__.py:8 models.py:492
+#: __init__.py:8 models.py:502
msgid "Multimedia files"
msgstr "Fichiers multimedias"
-#: __init__.py:9 models.py:541
+#: __init__.py:9 models.py:551
msgid "Picture files"
msgstr "Fichiers d'image"
@@ -107,357 +107,361 @@ msgstr "Courriel (optionnel) "
msgid "Object"
msgstr "Objet"
-#: forms.py:155
+#: forms.py:158
msgid "End date has been set with no start date"
msgstr "Une date de fin a été donnée sans date de début"
-#: forms.py:369
+#: forms.py:171
+msgid "This field is mandatory for the selected categories"
+msgstr "Ce champ est obligatoire pour les catégories sélectionnées"
+
+#: forms.py:385
msgid "File"
msgstr "Fichier"
-#: forms.py:375
+#: forms.py:391
msgid "Bad file format: this must be a GPX or KML file"
msgstr "Mauvais format de fichier : KML et GPX sont supportés"
-#: forms.py:380 models.py:48 models.py:101 models.py:122 models.py:135
-#: models.py:149 models.py:232 models.py:439 models.py:482 models.py:526
-#: models.py:557 models.py:794 models.py:806 models.py:891
+#: forms.py:396 models.py:49 models.py:102 models.py:123 models.py:136
+#: models.py:150 models.py:233 models.py:449 models.py:492 models.py:536
+#: models.py:567 models.py:804 models.py:816 models.py:901
#: templates/chimere/edit.html:39 templates/chimere/edit_route.html:36
msgid "Name"
msgstr "Nom"
-#: forms.py:389 models.py:843
+#: forms.py:405 models.py:853
msgid "Area"
msgstr "Zone"
-#: models.py:49 models.py:123 models.py:150 models.py:243 models.py:443
-#: models.py:812 models.py:893
+#: models.py:50 models.py:124 models.py:151 models.py:244 models.py:453
+#: models.py:822 models.py:903
msgid "Available"
msgstr "Disponible"
-#: models.py:50
+#: models.py:51 models.py:912
msgid "Date"
msgstr "Date"
-#: models.py:56 models.py:57
+#: models.py:57 models.py:58
msgid "News"
msgstr "Nouvelle"
-#: models.py:62
+#: models.py:63
msgid "Parameters"
msgstr "Paramètres"
-#: models.py:66
+#: models.py:67
msgid "TinyUrl"
msgstr "Mini-url"
-#: models.py:105 models.py:112 models.py:152
+#: models.py:106 models.py:113 models.py:153
msgid "Color theme"
msgstr "Thème de couleur"
-#: models.py:110
+#: models.py:111
msgid "Code"
msgstr "Code"
-#: models.py:111 models.py:124 models.py:154 models.py:484 models.py:533
-#: models.py:811 models.py:880 models.py:892
+#: models.py:112 models.py:125 models.py:155 models.py:494 models.py:543
+#: models.py:821 models.py:890 models.py:902
msgid "Order"
msgstr "Ordre"
-#: models.py:117
+#: models.py:118
msgid "Color"
msgstr "Couleur"
-#: models.py:130 models.py:148 templates/chimere/main_map.html:13
+#: models.py:131 models.py:149 templates/chimere/main_map.html:13
msgid "Category"
msgstr "Catégorie"
-#: models.py:136 models.py:435 models.py:527 models.py:622
+#: models.py:137 models.py:445 models.py:537 models.py:632
msgid "Image"
msgstr "Image"
-#: models.py:138 models.py:529 models.py:624
+#: models.py:139 models.py:539 models.py:634
msgid "Height"
msgstr "Hauteur"
-#: models.py:139 models.py:530 models.py:625
+#: models.py:140 models.py:540 models.py:635
msgid "Width"
msgstr "Largeur"
-#: models.py:143 models.py:151
+#: models.py:144 models.py:152
msgid "Icon"
msgstr "Icône"
-#: models.py:155
+#: models.py:156
msgid "Marker"
msgstr "Point d'intérêt"
-#: models.py:156 models.py:618 models.py:633
+#: models.py:157 models.py:628 models.py:643
#: templates/chimere/edit_route.html:27
msgid "Route"
msgstr "Trajet"
-#: models.py:157
+#: models.py:158
msgid "Both"
msgstr "Mixte"
-#: models.py:158
+#: models.py:159
msgid "Item type"
msgstr "Type d'élément"
-#: models.py:163
+#: models.py:164
msgid "Sub-category"
msgstr "Sous-catégorie"
-#: models.py:164
+#: models.py:165
msgid "Sub-categories"
msgstr "Sous-catégories"
-#: models.py:210
+#: models.py:211
msgid "Importer type"
msgstr "Type d'import"
-#: models.py:213 models.py:254
+#: models.py:214 models.py:255
msgid "Source"
msgstr "Source"
-#: models.py:215
+#: models.py:216
msgid "Filter"
msgstr "Filtre"
-#: models.py:218
+#: models.py:219
msgid "Associated subcategories"
msgstr "Sous-catégories associées"
-#: models.py:219
+#: models.py:220
msgid "State"
msgstr "État"
-#: models.py:221
+#: models.py:222
msgid "SRID"
msgstr "SRID"
-#: models.py:222
+#: models.py:223
msgid "Zipped file"
msgstr "Fichier zippé"
-#: models.py:225
+#: models.py:226
msgid "Importer"
msgstr "Import"
-#: models.py:234
+#: models.py:235
msgid "Submitter session key"
msgstr "Clé de session du demandeur"
-#: models.py:236
+#: models.py:237
msgid "Submitter name or nickname"
msgstr "Nom ou pseudo du demandeur"
-#: models.py:238
+#: models.py:239
msgid "Submitter email"
msgstr "Courriel du demandeur"
-#: models.py:240
+#: models.py:241
msgid "Submitter comment"
msgstr "Commentaire du demandeur"
-#: models.py:242
+#: models.py:243
msgid "Submited"
msgstr "Soumis"
-#: models.py:244
+#: models.py:245
msgid "Modified"
msgstr "Modifié"
-#: models.py:245
+#: models.py:246
msgid "Disabled"
msgstr "Désactivé"
-#: models.py:246
+#: models.py:247
msgid "Imported"
msgstr "Importé"
-#: models.py:247
+#: models.py:248
msgid "Excluded"
msgstr "Exclu"
-#: models.py:249
+#: models.py:250
msgid "Status"
msgstr "État"
-#: models.py:250
+#: models.py:251
msgid "Import key"
msgstr "Clé d'import"
-#: models.py:252
+#: models.py:253
msgid "Import version"
msgstr "Version de l'import"
-#: models.py:257 templates/chimere/edit.html:56
+#: models.py:258 templates/chimere/edit.html:56
#: templates/chimere/edit_route.html:52
msgid "Start date"
msgstr "Date de début"
-#: models.py:258
+#: models.py:259
msgid "Not mandatory. Set it for dated item such as event. Format YYYY-MM-DD"
msgstr ""
"Optionnel. Précisez ce champ pour les éléments datés comme un événement. "
"Format du champ : AAAA-MM-JJ"
-#: models.py:260 templates/chimere/edit.html:62
+#: models.py:261 templates/chimere/edit.html:62
#: templates/chimere/edit_route.html:58
msgid "End date"
msgstr "Date de fin"
-#: models.py:261
+#: models.py:262
msgid ""
"Not mandatory. Set it only if you have a multi-day event. Format YYYY-MM-DD"
msgstr ""
"Optionnel. Précisez ce champ seulement pour des événements durant plusieurs "
"jours. Format du champ : AAAA-MM-JJ"
-#: models.py:293
+#: models.py:294
msgid "Reference marker"
msgstr "Point d'intérêt de référence"
-#: models.py:294
+#: models.py:295
msgid "Localisation"
msgstr "Localisation"
-#: models.py:296
+#: models.py:297
msgid "Available Date"
msgstr "Date de mise en disponibilité"
-#: models.py:300 templates/chimere/edit.html:49
+#: models.py:301 templates/chimere/edit.html:49
#: templates/chimere/edit_route.html:46
msgid "Description"
msgstr "Description"
-#: models.py:339 models.py:915
+#: models.py:349 models.py:932
msgid "Point of interest"
msgstr "Point d'intérêt"
-#: models.py:433
+#: models.py:443
msgid "Audio"
msgstr "Audio"
-#: models.py:434
+#: models.py:444
msgid "Video"
msgstr "Vidéo"
-#: models.py:436
+#: models.py:446
msgid "Other"
msgstr "Autre"
-#: models.py:437
+#: models.py:447
msgid "Media type"
msgstr "Type de media"
-#: models.py:440
+#: models.py:450
msgid "Mime type"
msgstr "Type mime"
-#: models.py:442
+#: models.py:452
msgid "Inside an iframe"
msgstr "À l'intérieur d'un iframe"
-#: models.py:446
+#: models.py:456
msgid "Multimedia type"
msgstr "Type de multimedia"
-#: models.py:447
+#: models.py:457
msgid "Multimedia types"
msgstr "Types de multimedia"
-#: models.py:483
+#: models.py:493
msgid "Url"
msgstr "Url"
-#: models.py:486 models.py:531
+#: models.py:496 models.py:541
msgid "Display inside the description?"
msgstr "Apparaît dans la description ?"
-#: models.py:491
+#: models.py:501
msgid "Multimedia file"
msgstr "Fichier multimedia"
-#: models.py:540
+#: models.py:550
msgid "Picture file"
msgstr "Fichier d'image"
-#: models.py:558
+#: models.py:568
msgid "Raw file (gpx or kml)"
msgstr "Fichier brut (gpx ou kml)"
-#: models.py:559
+#: models.py:569
msgid "Simplified file"
msgstr "Fichier simplifié"
-#: models.py:561
+#: models.py:571
msgid "KML"
msgstr "KML"
-#: models.py:561
+#: models.py:571
msgid "GPX"
msgstr "GPX"
-#: models.py:566
+#: models.py:576
msgid "Route file"
msgstr "Fichier de trajet"
-#: models.py:567
+#: models.py:577
msgid "Route files"
msgstr "Fichiers de trajet"
-#: models.py:617
+#: models.py:627
msgid "Reference route"
msgstr "Trajet de référence"
-#: models.py:621
+#: models.py:631
msgid "Associated file"
msgstr "Fichier associé"
-#: models.py:795
+#: models.py:805
msgid "Layer code"
msgstr "Code pour la couche"
-#: models.py:801
+#: models.py:811
msgid "Layer"
msgstr "Couche"
-#: models.py:807
+#: models.py:817
msgid "Area urn"
msgstr "Urn de la zone"
-#: models.py:809 templates/chimere/blocks/welcome.html:3
+#: models.py:819 templates/chimere/blocks/welcome.html:3
msgid "Welcome message"
msgstr "Message d'accueil"
-#: models.py:813
+#: models.py:823
msgid "Upper left corner"
msgstr "Coin en haut à gauche"
-#: models.py:815
+#: models.py:825
msgid "Lower right corner"
msgstr "Coin en bas à droite"
-#: models.py:817
+#: models.py:827
msgid "Default area"
msgstr "Zone par défaut"
-#: models.py:818
+#: models.py:828
msgid "Only one area is set by default"
msgstr "Seule une zone est définie par défaut"
-#: models.py:822
+#: models.py:832
msgid "Sub-categories checked by default"
msgstr "Sous-catégories cochées par défaut"
-#: models.py:824
+#: models.py:834
msgid "Sub-categories dynamicaly displayed"
msgstr "Sous-categories affichées dynamiquement"
-#: models.py:825
+#: models.py:835
msgid ""
"If checked, categories are only displayed in the menu if they are available "
"on the current extent."
@@ -465,57 +469,68 @@ msgstr ""
"Si coché, les catégories sont disponibles sur le menu seulement si elles "
"apparaissent sur la zone affichée."
-#: models.py:829
+#: models.py:839 models.py:906
msgid "Restricted to theses sub-categories"
msgstr "Restreindre à ces sous-categories"
-#: models.py:830
+#: models.py:840
msgid "If no sub-category is set all sub-categories are available"
msgstr ""
"Si aucune sous-catégorie n'est définie toutes les sous-catégories sont "
"disponibles"
-#: models.py:832
+#: models.py:842
msgid "Link to an external CSS"
msgstr "Lien vers une feuille de style externe"
-#: models.py:834
+#: models.py:844
msgid "Restrict to the area extent"
msgstr "Restreindre à l'étendue de la zone"
-#: models.py:881
+#: models.py:891
msgid "Default layer"
msgstr "Couche par défaut"
-#: models.py:885 models.py:886
+#: models.py:895 models.py:896
msgid "Layers"
msgstr "Couches"
-#: models.py:894
+#: models.py:904
+msgid "Mandatory"
+msgstr "Obligatoire"
+
+#: models.py:907
+msgid ""
+"If no sub-category is set all the property applies to all sub-categories"
+msgstr ""
+"Si aucune sous-catégorie n'est précisée, cette propriété est disponible pour "
+"toutes les sous-catégories"
+
+#: models.py:909
msgid "Text"
msgstr "Texte"
-#: models.py:895
+#: models.py:910
msgid "Long text"
msgstr "Texte long"
-#: models.py:896
+#: models.py:911
msgid "Password"
msgstr "Mot de passe"
-#: models.py:900
+#: models.py:917
msgid "Type"
msgstr "Type"
-#: models.py:905 models.py:917
+#: models.py:922 models.py:934
msgid "Property model"
msgstr "Modèle de propriété"
-#: models.py:918
+#: models.py:935
msgid "Value"
msgstr "Valeur"
-#: models.py:922
+#: models.py:939
msgid "Property"
msgstr "Propriété"
@@ -619,15 +634,15 @@ msgstr "Mauvais paramètre"
msgid "There are missing field(s) and/or errors in the submited form."
msgstr "Il y a des champs manquants ou des erreurs dans ce formulaire."
-#: views.py:308
+#: views.py:312
msgid "Bad file. Please check it with an external software."
msgstr "Fichier incohérent. Merci de le vérifier avec un logiciel externe."
-#: views.py:430
+#: views.py:434
msgid "Comments/request on the map"
msgstr "Commentaires/requètes sur la carte"
-#: views.py:433
+#: views.py:437
msgid ""
"Thank you for your contribution. It will be taken into account. If you have "
"left your email you may be contacted soon for more details."
@@ -636,15 +651,15 @@ msgstr ""
"laissé votre courriel vous serez peut-être contacté bientôt pour plus de "
"détails."
-#: views.py:437
+#: views.py:441
msgid "Temporary error. Renew your message later."
msgstr "Erreur temporaire. Réenvoyez votre message plus tard."
-#: views.py:568
+#: views.py:572
msgid "No category available in this area."
msgstr "Pas de catégorie disponible sur cette zone."
-#: views.py:675
+#: views.py:679
msgid "Incorrect choice in the list"
msgstr "Choix incorrect dans la liste"
@@ -818,31 +833,32 @@ msgstr "indique un champ obligatoire"
msgid "Categories"
msgstr "Catégories"
-#: templates/chimere/edit.html:88
+#: templates/chimere/edit.html:113
msgid "Personal information"
msgstr "Informations personnelles"
-#: templates/chimere/edit.html:90
+#: templates/chimere/edit.html:115
msgid ""
"This fields are not mandatory. If you provided them they not will be made "
"public and they will only used to join you for this project."
-msgstr "Ces champs ne sont pas obligatoires. Si vous les renseignez, ils "
-"ne seront pas publiés et ne seront utilisés seulement pour vous joindre "
-"dans le cadre de ce projet."
+msgstr ""
+"Ces champs ne sont pas obligatoires. Si vous les renseignez, ils ne seront "
+"pas publiés et ne seront utilisés seulement pour vous joindre dans le cadre "
+"de ce projet."
-#: templates/chimere/edit.html:93
+#: templates/chimere/edit.html:118
msgid "Your name or nickname"
msgstr "Votre nom ou pseudo"
-#: templates/chimere/edit.html:98
+#: templates/chimere/edit.html:123
msgid "Your email"
msgstr "Votre courriel"
-#: templates/chimere/edit.html:103
+#: templates/chimere/edit.html:128
msgid "Comments about your submission"
msgstr "Commentaires au sujet de votre proposition"
-#: templates/chimere/edit.html:108 templates/chimere/edit_route.html:77
+#: templates/chimere/edit.html:133 templates/chimere/edit_route.html:77
msgid "Propose"
msgstr "Proposez"
diff --git a/chimere/migrations/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py b/chimere/migrations/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py
new file mode 100644
index 0000000..53ee3d4
--- /dev/null
+++ b/chimere/migrations/0027_auto__add_field_propertymodel_mandatory__chg_field_marker_submiter_com.py
@@ -0,0 +1,241 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'PropertyModel.mandatory'
+ db.add_column('chimere_propertymodel', 'mandatory',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
+
+ # Adding M2M table for field subcategories on 'PropertyModel'
+ db.create_table('chimere_propertymodel_subcategories', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('propertymodel', models.ForeignKey(orm['chimere.propertymodel'], null=False)),
+ ('subcategory', models.ForeignKey(orm['chimere.subcategory'], null=False))
+ ))
+ db.create_unique('chimere_propertymodel_subcategories', ['propertymodel_id', 'subcategory_id'])
+
+
+ # Changing field 'Marker.submiter_comment'
+ db.alter_column('chimere_marker', 'submiter_comment', self.gf('django.db.models.fields.TextField')(max_length=200, null=True))
+
+ # Changing field 'Route.submiter_comment'
+ db.alter_column('chimere_route', 'submiter_comment', self.gf('django.db.models.fields.TextField')(max_length=200, null=True))
+
+ def backwards(self, orm):
+ # Deleting field 'PropertyModel.mandatory'
+ db.delete_column('chimere_propertymodel', 'mandatory')
+
+ # Removing M2M table for field subcategories on 'PropertyModel'
+ db.delete_table('chimere_propertymodel_subcategories')
+
+
+ # Changing field 'Marker.submiter_comment'
+ db.alter_column('chimere_marker', 'submiter_comment', self.gf('django.db.models.fields.CharField')(max_length=200, null=True))
+
+ # Changing field 'Route.submiter_comment'
+ db.alter_column('chimere_route', 'submiter_comment', self.gf('django.db.models.fields.CharField')(max_length=200, null=True))
+
+ models = {
+ 'chimere.area': {
+ 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'dynamic_categories': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}),
+ 'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}),
+ 'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}),
+ 'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.arealayers': {
+ 'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'},
+ 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}),
+ 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.category': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Category'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.color': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Color'},
+ 'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.colortheme': {
+ 'Meta': {'object_name': 'ColorTheme'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.icon': {
+ 'Meta': {'object_name': 'Icon'},
+ 'height': ('django.db.models.fields.IntegerField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.importer': {
+ 'Meta': {'object_name': 'Importer'},
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'filtr': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
+ 'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'state': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'chimere.layer': {
+ 'Meta': {'object_name': 'Layer'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.marker': {
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'},
+ 'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'point': ('chimere.widgets.PointField', [], {}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}),
+ 'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.multimediafile': {
+ 'Meta': {'object_name': 'MultimediaFile'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+ },
+ 'chimere.multimediatype': {
+ 'Meta': {'object_name': 'MultimediaType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.news': {
+ 'Meta': {'object_name': 'News'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'content': ('django.db.models.fields.TextField', [], {}),
+ 'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+ },
+ 'chimere.picturefile': {
+ 'Meta': {'object_name': 'PictureFile'},
+ 'height': ('django.db.models.fields.IntegerField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}),
+ 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.property': {
+ 'Meta': {'object_name': 'Property'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}),
+ 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}),
+ 'value': ('django.db.models.fields.TextField', [], {})
+ },
+ 'chimere.propertymodel': {
+ 'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'mandatory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'properties'", 'blank': 'True', 'to': "orm['chimere.SubCategory']"}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '1'})
+ },
+ 'chimere.route': {
+ 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'},
+ 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}),
+ 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}),
+ 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}),
+ 'route': ('chimere.widgets.RouteField', [], {}),
+ 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+ 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.routefile': {
+ 'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'},
+ 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+ 'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+ },
+ 'chimere.subcategory': {
+ 'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Category']"}),
+ 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}),
+ 'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {})
+ },
+ 'chimere.tinyurl': {
+ 'Meta': {'object_name': 'TinyUrl'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ }
+ }
+
+ complete_apps = ['chimere'] \ No newline at end of file
diff --git a/chimere/models.py b/chimere/models.py
index 44265eb..ca608e8 100644
--- a/chimere/models.py
+++ b/chimere/models.py
@@ -25,6 +25,7 @@ import simplejson as json
from lxml import etree
from datetime import datetime, timedelta
from subprocess import Popen, PIPE
+import unidecode
from django.conf import settings
from django.contrib.gis.db import models
@@ -38,7 +39,7 @@ from django import forms
from django.utils.translation import ugettext_lazy as _
from chimere.widgets import PointField, RouteField, SelectMultipleField, \
- TextareaWidget
+ TextareaWidget, DatePickerWidget
from chimere.managers import BaseGeoManager
from chimere.utils import KMLManager, OSMManager, ShapefileManager
@@ -303,6 +304,15 @@ class Marker(GeographicItem):
def __unicode__(self):
return self.name
+ def __init__(self, *args, **kwargs):
+ super(Marker, self).__init__(*args, **kwargs)
+ # add read attributes for properties
+ for property in self.getProperties():
+ attr_name = unidecode.unidecode(property.propertymodel.name).lower()
+ attr_name = re.sub(r'\W+','_', attr_name.strip())
+ if not hasattr(self, attr_name):
+ setattr(self, attr_name, property.value)
+
def get_init_multi(self):
multis = [forms.model_to_dict(multi)
for multi in self.multimedia_files.all()]
@@ -891,12 +901,19 @@ class PropertyModel(models.Model):
name = models.CharField(_(u"Name"), max_length=150)
order = models.IntegerField(_(u"Order"))
available = models.BooleanField(_(u"Available"))
+ mandatory = models.BooleanField(_(u"Mandatory"))
+ subcategories = SelectMultipleField(SubCategory, related_name='properties',
+ blank=True, verbose_name=_(u"Restricted to theses sub-categories"),
+ help_text=_(u"If no sub-category is set all the property applies to all "
+ u"sub-categories"))
TYPE = (('T', _('Text')),
('L', _('Long text')),
- ('P', _('Password')))
+ ('P', _('Password')),
+ ('D', _("Date")))
TYPE_WIDGET = {'T':forms.TextInput,
'L':TextareaWidget,
- 'P':forms.PasswordInput}
+ 'P':forms.PasswordInput,
+ 'D':DatePickerWidget}
type = models.CharField(_(u"Type"), max_length=1, choices=TYPE)
def __unicode__(self):
return self.name
diff --git a/chimere/templates/chimere/edit.html b/chimere/templates/chimere/edit.html
index bdd8b99..447de71 100644
--- a/chimere/templates/chimere/edit.html
+++ b/chimere/templates/chimere/edit.html
@@ -69,10 +69,9 @@
<div class='bottomform'>
{% for field in form %}
{% for property in properties %}
- {% ifequal field.name property %}
+ {% ifequal field.name property.getNamedId %}
<div class="fieldWrapper">
- <label for="id_{{field.name}}">{% trans field.label %}</label>
- {{ field.errors }}
+ <label for="id_{{field.name}}">{% trans field.label %}{% if property.mandatory %} *{% endif %}</label>
{% if field.errors %}<div class='errors'>{{ field.errors }}</div>{% endif %}
{{ field }}
</div>
@@ -83,6 +82,32 @@
{% inline_formset "Multimedia files" formset_multi %}
{% inline_formset "Picture files" formset_picture %}
+ {% if filtered_properties %}
+ <script type='text/javascript'>
+ var cat_filters = new Array();
+ var cat_to_hide = new Array();
+ {% for property in filtered_properties %}
+ cat_to_hide.push('#id_{{property.getNamedId}}');
+ {% for subcat in property.subcategories.all %}
+ if(!cat_filters['{{subcat.id}}']) cat_filters['{{subcat.id}}'] = new Array();
+ cat_filters['{{subcat.id}}'].push('#id_{{property.getNamedId}}');
+ {% endfor %}
+ {% endfor %}
+ $('#id_categories').change(function(){
+ for (idx in cat_to_hide){
+ $(cat_to_hide[idx]).parent().hide();
+ }
+ var vals = $(this).val();
+ for (val_id in vals){
+ var val = vals[val_id];
+ for (ids in cat_filters[val]){
+ $(cat_filters[val][ids]).parent().show();
+ }
+ }
+ });
+ $('#id_categories').change();
+ </script>
+ {% endif %}
</div>
<div class='personalform'>
<h3>{% trans "Personal information"%}</h3>
diff --git a/chimere/views.py b/chimere/views.py
index 3a59d3a..3150258 100644
--- a/chimere/views.py
+++ b/chimere/views.py
@@ -253,6 +253,9 @@ def edit(request, area_name="", item_id=None, submited=False):
# get the "manualy" declared_fields. Ie: properties
declared_fields = form.declared_fields.keys()
+ declared_fields = PropertyModel.objects.filter(available=True).all()
+ filtered_properties = PropertyModel.objects.filter(available=True,
+ subcategories__id__isnull=False).all()
response_dct.update({
'actions':actions,
'action_selected':('contribute', 'edit'),
@@ -268,6 +271,7 @@ def edit(request, area_name="", item_id=None, submited=False):
init_item.point if init_item else None,
area_name=response_dct['area_name']),
'properties':declared_fields,
+ 'filtered_properties':filtered_properties,
'submited':submited
})
# manualy populate the custom widget
diff --git a/debian/control b/debian/control
index 7317430..92cfa21 100644
--- a/debian/control
+++ b/debian/control
@@ -4,6 +4,7 @@ Depends: python-django (>=1.3), python-gdal, python-psycopg2,
python-beautifulsoup, python-imaging, libjs-jquery,
libjs-jquery-ui, libjs-jquery-ui-theme-base,
postgresql-9.1, postgresql-9.1-postgis, gettext,
- python-simplejson, gpsbabel, python-django-south
+ python-simplejson, gpsbabel, python-django-south,
+ python-unidecode
Recommends: tinymce, python-django-celery, python-kombu
Suggests: libjs-jquery-ui-theme-south-street
diff --git a/docs/install.rst b/docs/install.rst
index 2f66879..d0f918a 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -32,6 +32,7 @@ Prerequisites
- `Beautiful Soup <http://www.crummy.com/software/BeautifulSoup/>`_
- python-simplejson
- python-gdal
+ - `unidecode <http://pypi.python.org/pypi/Unidecode>_
- `lxml <http://lxml.de/>`_
- `jquery <http://jquery.com/>`_ version 1.7.1 or better
- `jquery-ui <http://jqueryui.com/>`_
@@ -59,7 +60,8 @@ Linux distribution repositories. For instance on Debian Wheezy::
python-beautifulsoup tinymce apache2 libgeos-3.3.3 proj-bin gdal-bin \
python-gdal python-lxml python-psycopg2 python-imaging gettext \
postgresql-9.1 postgresql-9.1-postgis libjs-jquery libjs-jquery-ui \
- python-django-celery python-simplejson python-gdal gpsbabel
+ python-django-celery python-simplejson python-gdal python-unidecode \
+ gpsbabel
If these packages do not exist in your distribution's repository, please refer
to the applications' websites.
diff --git a/docs/upgrade.rst b/docs/upgrade.rst
index 9f36eb4..aca3985 100644
--- a/docs/upgrade.rst
+++ b/docs/upgrade.rst
@@ -44,14 +44,15 @@ Activate the backports: http://backports-master.debian.org/Instructions/
Then install the new dependencies::
apt-get install -t squeeze-backports python-django python-django-south \
- python-simplejson libjs-jquery-ui
+ python-simplejson libjs-jquery-ui python-unidecode
Debian Wheezy
+++++++++++++
.. code-block:: bash
- apt-get install python-django-south python-simplejson libjs-jquery-ui
+ apt-get install python-django-south python-simplejson libjs-jquery-ui \
+ python-unidecode
If you are planing to do major import consider the install of `Celery
<http://celeryproject.org/>`_.
diff --git a/requirements.txt b/requirements.txt
index e1f2c46..843a351 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,3 +5,4 @@ pil
lxml
south==0.7.3
simplejson
+unidecode