summaryrefslogtreecommitdiff
path: root/chimere/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'chimere/models.py')
-rw-r--r--chimere/models.py397
1 files changed, 127 insertions, 270 deletions
diff --git a/chimere/models.py b/chimere/models.py
index 15d264b..9a91a74 100644
--- a/chimere/models.py
+++ b/chimere/models.py
@@ -46,7 +46,8 @@ from chimere.widgets import HiddenPointChooserWidget, PointField, RouteField, \
DatePickerWidget
from chimere.managers import BaseGeoManager
from chimere.utils import KMLManager, OSMManager, ShapefileManager, \
- GeoRSSManager, CSVManager, HtmlXsltManager, XMLXsltManager
+ GeoRSSManager, CSVManager, HtmlXsltManager, XMLXsltManager, JsonManager
+
class Page(models.Model):
"""Simple extra pages
@@ -106,7 +107,7 @@ class News(models.Model):
date = models.DateField(_(u"Date"))
content = models.TextField()
url = models.URLField(_(u"Url"), max_length=200, blank=True, null=True)
- maps = SelectMultipleField('Map', verbose_name=_(u"Associated maps"),
+ areas = SelectMultipleField('Area', verbose_name=_(u"Associated areas"),
blank=True, null=True)
def __unicode__(self):
ordering = ["-date"]
@@ -172,8 +173,7 @@ class Color(models.Model):
"""
code = models.CharField(_(u"Code"), max_length=6)
order = models.IntegerField(_(u"Order"))
- color_theme = models.ForeignKey(ColorTheme, verbose_name=_(u"Color theme"),
- related_name='colors')
+ color_theme = models.ForeignKey(ColorTheme, verbose_name=_(u"Color theme"))
def __unicode__(self):
return self.code
class Meta:
@@ -184,7 +184,6 @@ class Category(models.Model):
"""Category of Point Of Interest (POI)
"""
name = models.CharField(_(u"Name"), max_length=150)
- slug = models.SlugField()
available = models.BooleanField(_(u"Available"))
order = models.IntegerField(_(u"Order"))
description = models.TextField(blank=True, null=True)
@@ -213,12 +212,9 @@ class SubCategory(models.Model):
category = models.ForeignKey(Category, verbose_name=_(u"Category"),
related_name='subcategories')
name = models.CharField(_(u"Name"), max_length=150)
- slug = models.SlugField()
available = models.BooleanField(_(u"Available"), default=True)
submission = models.BooleanField(_(u"Available for submission"),
default=True)
- weighted = models.BooleanField(_(u"Has an associated quantity"),
- default=False)
TYPE = (('M', _(u'Marker')),
('R', _(u'Route')),
('B', _(u'Both')),)
@@ -234,6 +230,8 @@ class SubCategory(models.Model):
default=False)
routing_warn = models.BooleanField(_(u"Routing warn"), default=False)
order = models.IntegerField(_(u"Order"), default=1000)
+ keywords = models.TextField(_(u"Keywords"), max_length=200,
+ blank=True, null=True)
def __unicode__(self):
return u"%s / %s" % (self.category.name, self.name)
class Meta:
@@ -242,7 +240,7 @@ class SubCategory(models.Model):
verbose_name_plural = _(u"Sub-categories")
@classmethod
- def getAvailable(cls, item_types=None, map_name=None, public=False):
+ def getAvailable(cls, item_types=None, area_name=None, public=False):
'''Get list of tuples with first the category and second the associated
subcategories
'''
@@ -255,14 +253,14 @@ class SubCategory(models.Model):
if public:
subcategories = subcategories.filter(submission=True)
selected_cats = []
- if map_name:
- map = Map.objects.get(urn=map_name)
+ if area_name:
+ area = Area.objects.get(urn=area_name)
# if there some restrictions with categories limit them
- if map.subcategories.count():
- sub_ids = [sub.id for sub in map.subcategories.all()]
+ if area.subcategories.count():
+ sub_ids = [sub.id for sub in area.subcategories.all()]
subcategories = subcategories.filter(id__in=sub_ids)
selected_cats = [subcat.pk
- for subcat in map.default_subcategories.all()]
+ for subcat in area.default_subcategories.all()]
for sub_category in subcategories.order_by('order'):
if sub_category.category not in sub_categories:
sub_categories[sub_category.category] = []
@@ -278,10 +276,10 @@ class SubCategory(models.Model):
return subcategories
@classmethod
- def getAvailableTuples(cls, item_types=None, map_name=None):
+ def getAvailableTuples(cls, item_types=None, area_name=None):
cats = []
for cat, subcats in cls.getAvailable(item_types=item_types,
- map_name=map_name):
+ area_name=area_name):
cats.append((unicode(cat),
[(subcat.pk, subcat.name) for subcat in subcats]))
return cats
@@ -304,13 +302,29 @@ class SubCategory(models.Model):
json_string = json.dumps(self.getJSONDict())
return json_string
-IMPORTERS = {'KML':KMLManager,
- 'OSM':OSMManager,
- 'SHP':ShapefileManager,
- 'RSS':GeoRSSManager,
- 'CSV':CSVManager,
- 'XSLT':HtmlXsltManager,
- 'XXLT':XMLXsltManager
+ @property
+ def slug(self):
+ return defaultfilters.slugify(self.name)
+
+ @property
+ def item_nb(self):
+ return Marker.objects.filter(categories=self).count()
+
+STATUS = (('S', _(u'Submited')),
+ ('A', _(u'Available')),
+ ('M', _(u'Modified')),
+ ('D', _(u'Disabled')),
+ ('I', _(u'Imported')))
+STATUS_DCT = dict(STATUS)
+
+IMPORTERS = {'KML': KMLManager,
+ 'OSM': OSMManager,
+ 'SHP': ShapefileManager,
+ 'RSS': GeoRSSManager,
+ 'CSV': CSVManager,
+ 'JSON': JsonManager,
+ 'XSLT': HtmlXsltManager,
+ 'XXLT': XMLXsltManager
}
IMPORTER_CHOICES = (('KML', 'KML'),
@@ -318,20 +332,21 @@ IMPORTER_CHOICES = (('KML', 'KML'),
('SHP', 'Shapefile'),
('RSS', 'GeoRSS'),
('CSV', 'CSV'),
+ ('JSON', 'JSON'),
('XSLT', 'HTML-XSLT'),
('XXLT', 'XML-XSLT'),
)
IMPORTER_CHOICES_DICT = dict(IMPORTER_CHOICES)
+
class Importer(models.Model):
'''
Data importer for a specific subcategory
'''
importer_type = models.CharField(_(u"Importer type"), max_length=4,
choices=IMPORTER_CHOICES)
- filtr = models.CharField(_(u"Filter"), max_length=200,
- blank=True, null=True)
+ filtr = models.TextField(_(u"Filter"), blank=True, null=True)
source = models.CharField(_(u"Web address"), max_length=200,
blank=True, null=True,
help_text=_(u"Don't forget the trailing slash"))
@@ -360,6 +375,8 @@ class Importer(models.Model):
u"a marker to a way"), default=False)
automatic_update = models.BooleanField(_(u"Automatically updated"),
default=False)
+ default_status = models.CharField(_(u"Default status"), max_length=1,
+ choices=STATUS, default='I')
default_localisation = PointField(_(u"Default localisation"),
srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION,
blank=True, null=True,
@@ -396,6 +413,7 @@ class Importer(models.Model):
dct[key_cat.key] = key_cat.category
return dct
+
class ImporterKeyCategories(models.Model):
"""
Association between key and categories
@@ -408,13 +426,6 @@ class ImporterKeyCategories(models.Model):
class Meta:
verbose_name = _(u"Importer - Key categories")
-STATUS = (('S', _(u'Submited')),
- ('A', _(u'Available')),
- ('M', _(u'Modified')),
- ('D', _(u'Disabled')),
- ('I', _(u'Imported')))
-STATUS_DCT = dict(STATUS)
-
class GeographicItem(models.Model):
name = models.CharField(_(u"Name"), max_length=150)
categories = SelectMultipleField(SubCategory)
@@ -473,7 +484,12 @@ class GeographicItem(models.Model):
if not _set:
new_keys += '%s:%s;' % (key, value)
self.import_key = new_keys
+ modified_since_import = self.modified_since_import
self.save()
+ # preserve modified_since_import
+ if modified_since_import != self.modified_since_import:
+ self.modified_since_import = modified_since_import
+ self.save()
def has_modified(self):
if (self.ref_item and self.ref_item != self) \
@@ -511,8 +527,6 @@ class Marker(GeographicItem):
null=True) # used by feeds
route = models.ForeignKey(u"Route", blank=True, null=True,
related_name='associated_marker')
- weight = models.IntegerField(_(u"Quantity"), blank=True, null=True,
- default=0)
description = models.TextField(_(u"Description"), blank=True, null=True)
is_front_page = models.NullBooleanField(_(u"Is front page"), blank=True,
null=True)
@@ -582,10 +596,6 @@ class Marker(GeographicItem):
def geom_attr(self):
return 'point'
- @property
- def has_weight(self):
- return bool(self.categories.filter(weighted=True).count())
-
class Meta:
ordering = ('status', 'name')
verbose_name = _(u"Point of interest")
@@ -667,32 +677,6 @@ class Marker(GeographicItem):
val = values[unicode(propertymodel.id)]
self.setProperty(propertymodel, val)
- PROPERTIES_KEYS = ['point', 'pk', 'name', 'weight']
- @classmethod
- def _getJson(cls, values, base_dct={"properties":{}}):
- item = base_dct.copy()
- item["geometry"] = {"type": "Point",
- "coordinates": [values['point'].x,
- values['point'].y]}
- item["properties"]['pk'] = values['pk']
- item["properties"]['name'] = values['name']
- if values['weight']:
- item["properties"]['weight'] = values['weight']
- return item
-
- def _getItems(self, base_dct={"properties":{}}):
- '''Return a dict representation for json
- '''
- item = base_dct.copy()
- item["geometry"] = {"type": "Point",
- "coordinates": [ self.point.x, self.point.y ]
- }
- item["properties"]['pk'] = self.pk
- item["properties"]['name'] = self.name
- if self.weight:
- item["properties"]['weight'] = self.weight
- return item
-
def getGeoJSON(self, categories_id=[]):
'''Return a GeoJSON string
'''
@@ -707,31 +691,14 @@ class Marker(GeographicItem):
'pk':self.id,
'name':self.name,
'icon_path':unicode(cat.icon.image),
- 'icon_hover_path':cat.hover_icon.image \
+ 'icon_hover_path':unicode(cat.hover_icon.image) \
if cat.hover_icon else '',
'category_name':cat.name})
- items['weight'] = ''
- if cat.weighted:
- if not self.weight:
- continue
- items['weight'] = self.weight
- if cat.color_theme and cat.color_theme.colors.count():
- items['colors'] += ["#%s"] % '", "#'.join(
- [color.code for color in cat.color_theme.colors.\
- order_by('order').all()])
try:
items['properties'].update({'icon_width':cat.icon.image.width,
'icon_height':cat.icon.image.height,})
except IOError:
pass
- if cat.weighted:
- if not self.weight:
- continue
- items['weight'] = u', "weight":%d' % self.weight
- if cat.color_theme and cat.color_theme.colors.count():
- items['weight'] += u', "colors":["#%s"]' % '", "#'.join(
- [color.code for color in cat.color_theme.colors.\
- order_by('order').all()])
jsons.append(items)
@@ -745,20 +712,20 @@ class Marker(GeographicItem):
if cats.count():
return cats.all()[0]
- def get_absolute_url(self, map_name=''):
+ def get_absolute_url(self, area_name=''):
parameters = 'current_feature=%d' % self.id
if self.default_category:
parameters += '&checked_categories=%s' % self.default_category.pk
urn = TinyUrl.getUrnByParameters(parameters)
- map_name = map_name + '/' if map_name else ''
- url = reverse('chimere:tiny', args=[map_name, urn])
+ area_name = area_name + '/' if area_name else ''
+ url = reverse('chimere:tiny', args=[area_name, urn])
return url
-
PRE_ATTRS = {
- 'Marker':('name', 'geometry', 'import_version', 'modified_since_import'),
+ 'Marker':('name', 'description', 'start_date', 'geometry', 'import_version',
+ 'modified_since_import'),
'Route':('name', 'geometry', 'import_version', 'modified_since_import'),
- 'Map':('urn', 'name'),
+ 'Area':('urn', 'name'),
}
def geometry_pre_save(cls, pre_save_geom_values):
def geom_pre_save(sender, **kwargs):
@@ -767,8 +734,9 @@ def geometry_pre_save(cls, pre_save_geom_values):
instance = kwargs['instance']
try:
instance = cls.objects.get(pk=instance.pk)
- pre_save_geom_values[instance.pk] = [getattr(instance, attr)
- for attr in PRE_ATTRS[cls.__name__]]
+ pre_save_geom_values[instance.pk] = dict(
+ [(attr, getattr(instance, attr))
+ for attr in PRE_ATTRS[cls.__name__]])
except ObjectDoesNotExist:
pass
return geom_pre_save
@@ -786,24 +754,25 @@ def geometry_post_save(pre_save_geom_values):
or kwargs['instance'].pk not in pre_save_geom_values:
return
instance = kwargs['instance']
- name, geometry, import_version, modified_since_import = \
- pre_save_geom_values[instance.pk]
+ pre = pre_save_geom_values[instance.pk]
# force the reinit of modified_since_import
- if modified_since_import != instance.modified_since_import:
+ if pre['modified_since_import'] != instance.modified_since_import:
return
- if (instance.import_version != import_version
+ if (instance.import_version != pre['import_version']
and instance.modified_since_import):
instance.modified_since_import = False
instance.save()
return
if instance.modified_since_import:
return
- if instance.name != name or instance.geometry != geometry:
+ if [key for key in pre if pre not in ('import_version',
+ 'modified_since_import') and
+ getattr(instance, key) != pre[key]]:
instance.modified_since_import = True
instance.save()
return geom_post_save
def marker_post_save(sender, **kwargs):
- if not kwargs['instance']:
+ if not kwargs['instance'] or kwargs['created']:
return
geometry_post_save(pre_save_marker_values)(sender, **kwargs)
post_save.connect(marker_post_save, sender=Marker)
@@ -1196,13 +1165,6 @@ class Route(GeographicItem):
properties.append(property)
return properties
- def _getItems(self, dct={'properties':{}}):
- dct['geometry'] = { "type": "LineString",
- "coordinates": [[point.x, point.y]
- for point in self.route]}
- dct['properties'].update({'id':self.id, 'name':self.name})
- return dct
-
def getGeoJSON(self, color="#000"):
'''Return a GeoJSON string
'''
@@ -1343,14 +1305,14 @@ class SimpleArea:
return True
return False
- def getCategories(self, status='A', filter_available=True, map_name=None):
+ def getCategories(self, status='A', filter_available=True, area_name=None):
"""
- Get categories for this map
+ Get categories for this area
"""
wheres = []
- if map_name:
+ if area_name:
subcategory_pks = []
- for cat, subcats in SubCategory.getAvailable(map_name=map_name):
+ for cat, subcats in SubCategory.getAvailable(area_name=area_name):
for subcat in subcats:
subcategory_pks.append(unicode(subcat.pk))
if filter_available:
@@ -1414,43 +1376,37 @@ class Layer(models.Model):
class Meta:
verbose_name = _("Layer")
-class Map(models.Model, SimpleArea):
- """A map
+class Area(models.Model, SimpleArea):
+ """Rectangular area of the map
"""
name = models.CharField(_(u"Name"), max_length=150)
- available = models.BooleanField(_(u"Available"))
- users = models.ManyToManyField(User, through='MapUsers')
- urn = models.SlugField(_(u"Map urn"), max_length=50, blank=True,
+ urn = models.SlugField(_(u"Area urn"), max_length=50, blank=True,
unique=True)
welcome_message = models.TextField(_(u"Welcome message"), blank=True,
null=True)
order = models.IntegerField(_(u"Order"), unique=True)
+ available = models.BooleanField(_(u"Available"))
upper_left_corner = models.PointField(_(u"Upper left corner"),
default='POINT(0 0)', srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
lower_right_corner = models.PointField(_(u"Lower right corner"),
default='POINT(0 0)', srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION)
- default = models.BooleanField(_(u"Default map"), default=False,
- help_text=_(u"Only one map is set by default"))
- layers = SelectMultipleField(Layer, related_name='maps',
- through='MapLayers', blank=True)
+ default = models.NullBooleanField(_(u"Default area"),
+ help_text=_(u"Only one area is set by default"))
+ layers = SelectMultipleField(Layer, related_name='areas',
+ through='AreaLayers', blank=True)
default_subcategories = SelectMultipleField(SubCategory, blank=True,
verbose_name=_(u"Sub-categories checked by default"))
dynamic_categories = models.NullBooleanField(
_(u"Sub-categories dynamicaly displayed"),
help_text=_(u"If checked, categories are only displayed in the menu if "
u"they are available on the current extent."))
- subcategories = SelectMultipleField(SubCategory, related_name='maps',
- blank=True, db_table='chimere_subcategory_maps',
+ subcategories = SelectMultipleField(SubCategory, related_name='areas',
+ blank=True, db_table='chimere_subcategory_areas',
verbose_name=_(u"Restricted to theses sub-categories"),
help_text=_(u"If no sub-category is set all sub-categories are "
u"available"))
external_css = models.URLField(_(u"Link to an external CSS"), blank=True,
null=True)
- cluster = models.BooleanField(u"Clustering map (weight of items are added)",
- default=False)
- public_read = models.BooleanField(_(u"Public can read the map"))
- public_propose = models.BooleanField(_(u"Public can propose item to the map"))
- public_write = models.BooleanField(_(u"Public can write without moderation to the map"))
restrict_to_extent = models.BooleanField(_(u"Restrict to the area extent"),
default=False)
objects = models.GeoManager()
@@ -1460,72 +1416,13 @@ class Map(models.Model, SimpleArea):
class Meta:
ordering = ('order', 'name')
- verbose_name = _("Map")
-
- def can_write(self, user=None):
- return bool(self.getAvailable(user=user, urn=self.urn, single=True,
- edit=True))
-
- def can_propose(self, user=None):
- return bool(self.getAvailable(user=user, urn=self.urn, single=True,
- propose=True))
+ verbose_name = _("Area")
@classmethod
- def getAvailable(cls, user=None, urn=None, single=False, edit=False,
- propose=False):
- '''Get available maps
+ def getAvailable(cls):
+ '''Get available areas
'''
- map_filter = {'available':True}
- if urn:
- map_filter['urn'] = urn
- elif single:
- map_filter['default'] = True
- filters = []
- if not propose and not edit:
- filters = [{'public_write':True},
- {'public_propose':True},
- {'public_read':True}]
- elif propose:
- filters = [{'public_write':True},
- {'public_propose':True}]
- elif edit:
- filters = [{'public_write':True}]
- if user and user.is_authenticated():
- if not propose and not edit:
- filters += [
- {'mapusers__user':user, 'mapusers__read':True},
- {'mapusers__user':user, 'mapusers__write':True},
- {'mapusers__user':user, 'mapusers__propose':True},
- {'mapgroups__group__user':user, 'mapgroups__read':True},
- {'mapgroups__group__user':user, 'mapgroups__write':True},
- {'mapgroups__group__user':user, 'mapgroups__propose':True}
- ]
- elif propose:
- filters += [
- {'mapusers__user':user, 'mapusers__write':True},
- {'mapusers__user':user, 'mapusers__propose':True},
- {'mapgroups__group__user':user, 'mapgroups__write':True},
- {'mapgroups__group__user':user, 'mapgroups__propose':True}
- ]
- elif edit:
- filters += [
- {'mapusers__user':user, 'mapusers__write':True},
- {'mapgroups__group__user':user, 'mapgroups__write':True},
- ]
- query = None
- for fltr in filters:
- fltr.update(map_filter)
- if not query:
- query = Q(**fltr)
- else:
- query = query | Q(**fltr)
- maps = cls.objects.filter(query).distinct()
- if single:
- if not maps.count():
- return
- return maps.all()[0]
- else:
- return maps.all()
+ return cls.objects.filter(available=True)
def getWkt(self):
return "SRID=%d;POLYGON((%f %f,%f %f,%f %f,%f %f, %f %f))" % (
@@ -1549,66 +1446,54 @@ class Map(models.Model, SimpleArea):
"""
return Q(route__contained=self.getWkt())
-pre_save_map_values = {}
-def map_pre_save(sender, **kwargs):
+pre_save_area_values = {}
+def area_pre_save(sender, **kwargs):
if not kwargs['instance']:
return
- geometry_pre_save(Map, pre_save_map_values)(sender, **kwargs)
-pre_save.connect(map_pre_save, sender=Map)
+ geometry_pre_save(Area, pre_save_area_values)(sender, **kwargs)
+pre_save.connect(area_pre_save, sender=Area)
-def map_post_save(sender, **kwargs):
+def area_post_save(sender, **kwargs):
if not kwargs['instance']:
return
- map = kwargs['instance']
- if map.default:
- defaults = Map.objects.filter(default=True).exclude(pk=map.pk)
+ area = kwargs['instance']
+ if area.default:
+ defaults = Area.objects.filter(default=True).exclude(pk=area.pk)
for default in defaults:
default.default = False
default.save()
# manage permissions
- old_urn, old_name = map.urn, map.name
- if map.pk in pre_save_map_values:
- old_urn, old_name = pre_save_map_values[map.pk]
+ old_urn, old_name = area.urn, area.name
+ if area.pk in pre_save_area_values:
+ old_urn, old_name = pre_save_area_values[area.pk]
perm, old_groups, old_users = None, [], []
-
- if map.urn != old_urn:
- oldmnemo = 'change_map_' + old_urn
+ if area.urn != old_urn:
+ oldmnemo = 'change_area_' + old_urn
old_perm = Permission.objects.filter(codename=oldmnemo)
if old_perm.count():
perm = old_perm.all()[0]
- codename = 'change_map_' + map.urn
- if not Permission.objects.filter(codename=codename).count():
- perm.codename = codename
- perm.save()
- if not map.urn:
- map.urn = defaultfilters.slugify(map.name)
- map.save()
-
- # fix old mnemo
- oldmnemo = 'change_area_' + old_urn
- old_perm = Permission.objects.filter(codename=oldmnemo)
- if old_perm.count():
- perm = old_perm.all()[0]
- perm.codename = 'change_map_' + map.urn
- perm.save()
-
- mnemo = 'change_map_' + map.urn
+ perm.codename = 'change_area_' + area.urn
+ perm.save()
+ if not area.urn:
+ area.urn = defaultfilters.slugify(area.name)
+ area.save()
+ mnemo = 'change_area_' + area.urn
perm = Permission.objects.filter(codename=mnemo)
- lbl = "Can change " + map.name
+ lbl = "Can change " + area.name
if not perm.count():
content_type, created = ContentType.objects.get_or_create(
- app_label="chimere", model="map")
+ app_label="chimere", model="area")
perm = Permission(name=lbl, content_type_id=content_type.id,
codename=mnemo)
perm.save()
else:
perm = perm.all()[0]
- if old_name != map.name:
+ if old_name != area.name:
perm.name = lbl
perm.save()
# manage moderation group
- groupname = map.name + " moderation"
- if old_name != map.name:
+ groupname = area.name + " moderation"
+ if old_name != area.name:
old_groupname = old_name + " moderation"
old_gp = Group.objects.filter(name=old_groupname)
if old_gp.count():
@@ -1629,56 +1514,36 @@ def map_post_save(sender, **kwargs):
for p in Permission.objects.filter(content_type=ct).all():
group.permissions.add(p)
-post_save.connect(map_post_save, sender=Map)
+post_save.connect(area_post_save, sender=Area)
-def get_maps_for_user(user):
+def get_areas_for_user(user):
"""
- Getting maps for a specific user
+ Getting subcats for a specific user
"""
perms = user.get_all_permissions()
- maps = set()
- prefix = 'chimere.change_map_'
+ areas = set()
+ prefix = 'chimere.change_area_'
for perm in perms:
if perm.startswith(prefix):
try:
- map = Map.objects.get(urn=perm[len(prefix):])
- maps.add(map)
+ area = Area.objects.get(urn=perm[len(prefix):])
+ areas.add(area)
except ObjectDoesNotExist:
pass
- return maps
+ return areas
-def get_users_by_map(map):
- if not map:
+def get_users_by_area(area):
+ if not area:
return []
- perm = 'change_map_'+map.urn
+ perm = 'change_area_'+area.urn
return User.objects.filter(Q(groups__permissions__codename=perm)|
Q(user_permissions__codename=perm)).all()
-class MapUsers(models.Model):
- map = models.ForeignKey(Map, related_name='mapusers')
- user = models.ForeignKey(User, related_name='mapusers')
- read = models.BooleanField(_(u"Can read the map"))
- propose = models.BooleanField(_(u"Can propose item to the map"))
- write = models.BooleanField(_(u"Can write without moderation to the map"))
- class Meta:
- verbose_name = _("Map - user")
- verbose_name_plural = _("Map - users")
-
-class MapGroups(models.Model):
- map = models.ForeignKey(Map, related_name='mapgroups')
- group = models.ForeignKey(Group, related_name='mapgroups')
- read = models.BooleanField(_(u"Can read the map"))
- propose = models.BooleanField(_(u"Can propose item to the map"))
- write = models.BooleanField(_(u"Can write without moderation to the map"))
- class Meta:
- verbose_name = _("Map - group")
- verbose_name_plural = _("Map - groups")
-
-class MapLayers(models.Model):
- map = models.ForeignKey(Map)
+class AreaLayers(models.Model):
+ area = models.ForeignKey(Area)
layer = models.ForeignKey(Layer)
order = models.IntegerField(_(u"Order"))
- default = models.BooleanField(_(u"Default layer"), default=False)
+ default = models.NullBooleanField(_(u"Default layer"))
class Meta:
ordering = ('order',)
@@ -1692,7 +1557,6 @@ class PropertyModel(models.Model):
order = models.IntegerField(_(u"Order"))
available = models.BooleanField(_(u"Available"))
mandatory = models.BooleanField(_(u"Mandatory"))
- slug = models.SlugField()
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 "
@@ -1701,7 +1565,6 @@ class PropertyModel(models.Model):
('L', _('Long text')),
('P', _('Password')),
('D', _("Date")),
- ('B', _("Boolean")),
('C', _("Choices")),
('B', _("Boolean")),
)
@@ -1720,7 +1583,8 @@ class PropertyModel(models.Model):
verbose_name = _("Property model")
def getAttrName(self):
- attr_name = self.slug.replace('-', '_')
+ attr_name = defaultfilters.slugify(self.name)
+ attr_name = re.sub(r'-','_', attr_name)
return attr_name
def getNamedId(self):
@@ -1728,11 +1592,6 @@ class PropertyModel(models.Model):
'''
return 'property_%d_%d' % (self.order, self.id)
- def save(self, *args, **kwargs):
- if not self.slug:
- self.slug = defaultfilters.slugify(self.name)
- super(PropertyModel, self).save(*args, **kwargs)
-
class PropertyModelChoice(models.Model):
'''Choices for property model
'''
@@ -1753,9 +1612,10 @@ class Property(models.Model):
propertymodel = models.ForeignKey(PropertyModel,
verbose_name=_(u"Property model"))
value = models.TextField(_(u"Value"))
-
def __unicode__(self):
- if self.value and self.propertymodel.type == 'C':
+ if self.propertymodel.type == 'C':
+ if not self.value:
+ return ''
try:
return unicode(PropertyModelChoice.objects.get(
pk=self.value).value)
@@ -1763,9 +1623,6 @@ class Property(models.Model):
return ""
return unicode(self.value)
- def label(self):
- return unicode(self)
-
class Meta:
verbose_name = _(u"Property")
@@ -1779,7 +1636,7 @@ class Property(models.Model):
if self.propertymodel.type == 'C' and self.value:
try:
return PropertyModelChoice.objects.get(pk=self.value)
- except self.DoesNotExist:
+ except (self.DoesNotExist, ValueError):
return None
else:
return self.value