diff options
Diffstat (limited to 'chimere/models.py')
-rw-r--r-- | chimere/models.py | 397 |
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 |