Hi,
I’m coming from Flask and have the reflex to load the current request (or “g”) via the import of the module, which is not how Sanic behave.
Reading https://github.com/sanic-org/sanic/issues/69 kind of explains the reasons and motivations about it, but I have an implementation question coming from this.
Imagine the current scenario:
You have an endpoint: “POST /tags/” to create a new tag for your users
You have a middleware before that, that loads the currently connected user to request.ctx.user
On your endpoint, you pass the request.json
to your a Form validation system to ensure that the tag name matches the correct rules (not too long, slug, etc).
Ideally too, on the Form validation, you would test if that name is not present on the database where you’ll save it, for that connected user.
That’s where I’m stuck. Back in the old day with Flask, I would do something like this (simplified):
from .models import Tag
class FormTag(BaseForm):
name = Field(validators=[Length(max=25), Slug()])
def validate_name(self):
if Tag.find(self.name, request.ctx.user.id):
raise ValidationError('This tag already exists')
@app.post('/tags/')
def add_tag(request):
form = FormTag(request.json)
tag = Tag.add(form.name)
return json(tag))
Of course, I can’t access the request.ctx.user
from the form since it’s not available that easily.
I could do the validation on the endpoint, but that’s not semantically correct : the validation should be on the form’s end.
My question is kind of a dual purpose: to show a common example to answer the question asked on the Github ticket (https://github.com/sanic-org/sanic/issues/69#issuecomment-761893451) and to hopefully find a proper and clean alternative way that works with Sanic?
Thanks in advance!