summaryrefslogtreecommitdiff
path: root/chimere/main/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'chimere/main/models.py')
-rw-r--r--chimere/main/models.py121
1 files changed, 79 insertions, 42 deletions
diff --git a/chimere/main/models.py b/chimere/main/models.py
index f633b3f..093918b 100644
--- a/chimere/main/models.py
+++ b/chimere/main/models.py
@@ -20,6 +20,8 @@
"""
Models description
"""
+from datetime import datetime, timedelta
+
from django.utils.translation import ugettext_lazy as _
from django.contrib.gis.db import models
@@ -27,8 +29,7 @@ from django.contrib.gis.gdal import SpatialReference
from django.contrib import admin
from chimere import settings
-from chimere.main.widgets import PointField, RouteField, \
- ManyToManyField_NoSyncdb
+from chimere.main.widgets import PointField, RouteField, SelectMultipleField
class News(models.Model):
"""News of the site
@@ -42,6 +43,7 @@ class News(models.Model):
return self.title
class Meta:
verbose_name = _("News")
+ verbose_name_plural = _("News")
class TinyUrl(models.Model):
"""Tinyfied version of permalink parameters
@@ -122,6 +124,8 @@ class Icon(models.Model):
name = models.CharField(_("Name"), max_length=150)
image = models.ImageField(_("Image"), upload_to='icons',
height_field='height', width_field='width')
+ height = models.IntegerField(_("Height"))
+ width = models.IntegerField(_("Width"))
def __unicode__(self):
return self.name
class Meta:
@@ -133,8 +137,7 @@ class SubCategory(models.Model):
category = models.ForeignKey(Category, verbose_name=_("Category"))
name = models.CharField(_("Name"), max_length=150)
available = models.BooleanField(_("Available"))
- areas = models.ManyToManyField('Area', related_name='areas',
- blank=True, null=True)
+ areas = SelectMultipleField('Area', related_name='areas', blank=True)
icon = models.ForeignKey(Icon, verbose_name=_("Icon"))
color_theme = models.ForeignKey(ColorTheme, verbose_name=_("Color theme"),
blank=True, null=True)
@@ -163,8 +166,8 @@ class SubCategory(models.Model):
if area_name:
area = Area.objects.get(urn=area_name)
# if there some restrictions with categories limit them
- if area.subcategories.count():
- sub_ids = [sub.id for sub in area.subcategories.all()]
+ if area.subcategory_set.count():
+ sub_ids = [sub.id for sub in area.subcategory_set.all()]
# if no area is defined for a category don't filter it
sub_ids += [sub.id for sub in subcategories
if not sub.areas.count()]
@@ -183,10 +186,12 @@ class Marker(models.Model):
'''Marker for a POI
'''
name = models.CharField(_("Name"), max_length=150)
- subcategory = models.ForeignKey(SubCategory, verbose_name=_("Subcategory"))
- point = PointField(_("Localisation"))
+ categories = SelectMultipleField(SubCategory)
+ point = PointField(_("Localisation"), srid=settings.EPSG_DISPLAY_PROJECTION)
picture = models.ImageField(_("Image"), upload_to='upload', blank=True,
- height_field='height', width_field='width')
+ null=True, height_field='height', width_field='width')
+ height = models.IntegerField(_("Height"), blank=True, null=True)
+ width = models.IntegerField(_("Width"), blank=True, null=True)
STATUS = (('S', _('Submited')),
('A', _('Available')),
('D', _('Disabled')),)
@@ -194,13 +199,23 @@ class Marker(models.Model):
for key, label in STATUS:
STATUS_DCT[key] = label
status = models.CharField(_("Status"), max_length=1, choices=STATUS)
+ if settings.DAYS_BEFORE_EVENT:
+ start_date = models.DateField(_("Start date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it for dated item such as event. \
+Format YYYY-MM-DD"))
+ end_date = models.DateField(_("End date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it only if you have a multi-day event. \
+Format YYYY-MM-DD"))
+ if 'chimere.rss' in settings.INSTALLED_APPS:
+ available_date = models.DateTimeField(_("Available Date"), blank=True,
+ null=True)
objects = models.GeoManager()
def __unicode__(self):
return self.name
class Meta:
- ordering = ('subcategory__category', 'subcategory', 'status', 'name')
+ ordering = ('status', 'name')
verbose_name = _("Point of interest")
def getLatitude(self):
@@ -236,31 +251,44 @@ class Marker(models.Model):
properties.append(property)
return properties
- def getGeoJSON(self):
+ def getGeoJSON(self, categories_id=[]):
'''Return a GeoJSON string
'''
- return """{"type":"Feature", "geometry":%(geometry)s, \
+ jsons = []
+ for cat in self.categories.all():
+ if categories_id and cat.id not in categories_id:
+ continue
+ jsons.append("""{"type":"Feature", "geometry":%(geometry)s, \
"properties":{"pk": %(id)d, "name": "%(name)s", \
"icon_path":"%(icon_path)s", "icon_width":%(icon_width)d, \
"icon_height":%(icon_height)d}}""" % {'id':self.id, 'name':self.name,
-'icon_path':self.subcategory.icon.image, 'geometry':self.point.geojson,
-'icon_width':self.subcategory.icon.image.width,
-'icon_height':self.subcategory.icon.image.height,}
+'icon_path':cat.icon.image, 'geometry':self.point.geojson,
+'icon_width':cat.icon.image.width, 'icon_height':cat.icon.image.height,})
+ return ",".join(jsons)
class Route(models.Model):
'''Route on the map
'''
name = models.CharField(_("Name"), max_length=150)
- subcategory = models.ForeignKey(SubCategory, verbose_name=_("Subcategory"))
- route = RouteField(_("Route"))
+ categories = SelectMultipleField(SubCategory)
+ route = RouteField(_("Route"), srid=settings.EPSG_DISPLAY_PROJECTION)
picture = models.ImageField(_("Image"), upload_to='upload', blank=True,
- height_field='height', width_field='width')
+ null=True, height_field='height', width_field='width')
+ height = models.IntegerField(_("Height"), blank=True, null=True)
+ width = models.IntegerField(_("Width"), blank=True, null=True)
STATUS = (('S', _('Submited')),
('A', _('Available')),
('D', _('Disabled')),)
STATUS_DCT = {}
for key, label in STATUS:
STATUS_DCT[key] = label
+ if settings.DAYS_BEFORE_EVENT:
+ start_date = models.DateField(_("Start date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it for dated item such as event. \
+Format YYYY-MM-DD"))
+ end_date = models.DateField(_("End date"), blank=True, null=True,
+help_text=_("Not mandatory. Set it only if you have a multi-day event. \
+Format YYYY-MM-DD"))
status = models.CharField(_("Status"), max_length=1, choices=STATUS)
objects = models.GeoManager()
@@ -268,7 +296,7 @@ class Route(models.Model):
return self.name
class Meta:
- ordering = ('subcategory__category', 'subcategory', 'status', 'name')
+ ordering = ('status', 'name')
verbose_name = _("Route")
def getProperty(self, propertymodel, safe=None):
@@ -304,6 +332,22 @@ class Route(models.Model):
"color":"%(color)s"}}""" % {'id':self.id, 'name':self.name,
'color':color, 'geometry':self.route.geojson,}
+def getDateCondition():
+ '''
+ Return an SQL condition for apparition of dates
+ '''
+ if not settings.DAYS_BEFORE_EVENT:
+ return ""
+ now = datetime.now().strftime('%Y-%m-%d')
+ after = (datetime.now() + timedelta(settings.DAYS_BEFORE_EVENT)
+ ).strftime('%Y-%m-%d')
+ date_condition = " and %(alias)s.start_date is null or "
+ date_condition += "(%(alias)s.start_date >= '" + now + "' and "
+ date_condition += "%(alias)s.start_date <='" + after + "')"
+ date_condition += " or (%(alias)s.start_date <='" + now + "' and "
+ date_condition += "%(alias)s.end_date >='" + now + "') "
+ return date_condition
+
class SimplePoint:
"""
Point in the map (not in the database)
@@ -352,39 +396,35 @@ class SimpleArea:
self.upper_left_corner.x, self.upper_left_corner.y,
settings.EPSG_DISPLAY_PROJECTION
)
+ date_condition = getDateCondition()
sql_main = '''select subcat.id as id, subcat.category_id as category_id,
subcat.name as name, subcat.available as available, subcat.icon_id as icon_id,
subcat.color_theme_id as color_theme_id, subcat.order as order,
subcat.item_type as item_type from main_subcategory subcat
inner join main_category cat on cat.id=subcat.category_id'''
sql = sql_main + '''
-inner join main_marker mark on mark.subcategory_id=subcat.id
- and ST_Contains(%s, mark.point)''' % area
+inner join main_marker mark on ST_Contains(%s, mark.point)''' % area
if equal_status:
sql += ' and mark.status' + equal_status
+ sql += date_condition % {'alias':'mark'}
+ sql += '''
+inner join main_marker_categories mc on mc.subcategory_id=subcat.id and
+mc.marker_id=mark.id'''
if filter_available:
sql += ' where subcat.available = TRUE and cat.available = TRUE'
- print sql
- # django > 1.1
- #subcats = SubCategory.objects.raw(sql)
- from django.db import connection, transaction
- cursor = connection.cursor()
- cursor.execute(sql, [])
- subcats = set()
- for r in cursor.fetchall():
- subcats.add(SubCategory.objects.get(id=r[0]))
+ subcats = set(SubCategory.objects.raw(sql))
sql = sql_main + '''
-inner join main_route rt on rt.subcategory_id=subcat.id
-and (ST_Intersects(%s, rt.route) or ST_Contains(%s, rt.route))''' % (area, area)
+inner join main_route rt on (ST_Intersects(%s, rt.route) or
+ST_Contains(%s, rt.route))''' % (area, area)
if equal_status:
sql += ' and rt.status' + equal_status
+ sql += date_condition % {'alias':'rt'}
+ sql += '''
+inner join main_route_categories rc on rc.subcategory_id=subcat.id and
+rc.route_id=rt.id'''
if filter_available:
sql += ' where subcat.available = TRUE and cat.available = TRUE'
- # django > 1.1
- #subcats += SubCategory.objects.raw(sql)
- cursor.execute(sql, [])
- for r in cursor.fetchall():
- subcats.add(SubCategory.objects.get(id=r[0]))
+ subcats.union(SubCategory.objects.raw(sql))
return subcats
class Area(models.Model, SimpleArea):
@@ -393,15 +433,12 @@ class Area(models.Model, SimpleArea):
name = models.CharField(_("Name"), max_length=150)
urn = models.SlugField(_("Area urn"), max_length=50, blank=True,
unique=True)
- subcategories = ManyToManyField_NoSyncdb(SubCategory,
- related_name='subcategories', blank=True, null=True,
- db_table=u'subcategory_areas')
order = models.IntegerField(_("Order"))
available = models.BooleanField(_("Available"))
upper_left_corner = models.PointField(_("Upper left corner"),
- default='POINT(0 0)')
+ default='POINT(0 0)', srid=settings.EPSG_DISPLAY_PROJECTION)
lower_right_corner = models.PointField(_("Lower right corner"),
- default='POINT(0 0)')
+ default='POINT(0 0)', srid=settings.EPSG_DISPLAY_PROJECTION)
objects = models.GeoManager()
def __unicode__(self):