diff --git a/app/controllers/base.py b/app/controllers/base.py index bbea4d71fd54712fed3ed5cd194800886617d2b7..6b6c143a890052ab90c2c4f0d2a7444e5338928a 100644 --- a/app/controllers/base.py +++ b/app/controllers/base.py @@ -88,8 +88,8 @@ class RestController(object): raise NotFound return model - def post(self, data, filter_data): - """Post a new model from a dictionary.""" + def create(self, data, filter_data): + """Creates a model, but does not add it to the database.""" model = self.Model() form = self.get_form(filter_data)(formdata=MultiDict(data)) @@ -97,6 +97,11 @@ class RestController(object): raise BadRequest(form.errors) form.populate_obj(model) + return model + + def post(self, data, filter_data): + """Post a new model from a dictionary.""" + model = self.create(data, filter_data) db.session.add(model) self.commit() diff --git a/app/models/project.py b/app/models/project.py index 36e3c770dd7aaeab2a8aaa467de0944cc0acc11b..af250c46e15089f713a5670af1bbaa87ce680c0b 100644 --- a/app/models/project.py +++ b/app/models/project.py @@ -1,10 +1,36 @@ """Models directly-relating to the top-level project.""" +import re from app.lib.database import db from app.models.base import Model, Tracked, SalesForce class Project(Model, Tracked, SalesForce, db.Model): """A project.""" + client_id = db.Column( + db.Integer, db.ForeignKey('client.id'), nullable=False) + place_id = db.Column( + db.Integer, db.ForeignKey('place.id'), nullable=False) + + name = db.Column(db.Unicode(255), nullable=False) + + @property + def computed_slug(self): + """Compute a slug by doing the following: + - Lowercase the name. + - Replace spaces with "-". Replace "/", "?", "=", "&", and ":" + with nothing. + - Truncate to 200 characters. + - Append a dash and the id. + """ + slug = self.name.lower() + slug = re.sub( + r'(\s|\/|\?|\=|\&|:)/g', + lambda m: '-' if m.group(0).isspace() else '', + slug) + slug = slug[:200] + slug = '{}-{}'.format(slug, self.id) + return slug + # TODO SQLAlchemy < 1.1 does not support the use of a python enum in Enum # fields, so for now we have to use a list of strings. When 1.1 leaves # beta, this should be ported to the Enum below. @@ -33,17 +59,17 @@ class Project(Model, Tracked, SalesForce, db.Model): 'customer_reviewed', 'approved', 'financed', 'contracted', 'constructed', 'verified', 'paid' ] - - client_id = db.Column( - db.Integer, db.ForeignKey('client.id'), nullable=False) - place_id = db.Column( - db.Integer, db.ForeignKey('place.id'), nullable=False) - name = db.Column(db.Unicode(255), nullable=False) state = db.Column( db.Enum(*states, name='project_states'), default='pending', nullable=False) + def get_dictionary(self): + """Add the calculated slug to the dictionary.""" + d = super(Project, self).get_dictionary() + d.update({'slug': self.computed_slug}) + return d + class ProjectStateChange(Model, Tracked, db.Model): """A state change of a project."""