\$\begingroup\$

I'm using Flask along with Flask-SQLAlchemy and Flask-WTF.

I have a model:

class Trip(db.Model): id = db.Column(db.BigInteger, primary_key=True) author_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True, nullable=False) name = db.Column(db.String(2000), nullable=False) country_code = db.Column(db.String(2)) slug = db.Column(db.String(2000), nullable=False) author = db.relationship('User', backref=db.backref('trips', order_by=lambda: Trip.name)) def __repr__(self): return f"<Trip {self.id} author_id={self.author_id} slug={self.slug}>" db.Index('idx_trip_author_slug', Trip.author_id, Trip.slug, unique=True)

To create and update trips, I use class-based views like this:

class TripCUView(MethodView): methods = ('GET', 'POST') decorators = [user_required] title = 'Trip action' submit_text = 'Save' def dispatch_request(self, *args, **kwargs): self.model = self._instant_model() return super().dispatch_request(*args, **kwargs) def get(self): self.form = self._build_form() return self._default_render() def post(self): self.form = TripForm() if self.form.validate(): try: self.form.populate_obj(self.model) db.session.add(self.model) db.session.commit() return redirect(url_for('.index')) except IntegrityError as e: db.session.rollback() if (e.orig.pgcode == pgerrorcodes.UNIQUE_VIOLATION): self.form.errors.setdefault('slug', []) self.form.errors['slug'].append('Already exists') return self._default_render() else: raise e return self._default_render() def _build_form(self): raise NotImplementedError def _instant_model(self) -> Trip: raise NotImplementedError def _default_render(self): return render_template('form.html', form=self.form, title=self.title, submit_text=self.submit_text) class CreateTripView(TripCUView): title = 'Create trip' def _build_form(self): return TripForm() def _instant_model(self): return Trip(author=g.user) class UpdateTripView(TripCUView): @property def title(self): return f"Updating {self.model.name}" def dispatch_request(self, slug): self.slug = slug return super().dispatch_request() def _build_form(self): return TripForm(obj=self.model) def _instant_model(self): return Trip.query\ .filter_by(slug=self.slug, author=g.user)\ .first_or_404() trips.add_url_rule('/new', view_func=CreateTripView.as_view('new')) trips.add_url_rule('/<slug>/update', view_func=UpdateTripView.as_view('update'))

Basically, I override the post method on my MethodView subclass to check for integrity errors and translate them into form errors if they are indeed uniqueness violations.

Can it be done better?