Closed mojimi closed 5 years ago
Hi
Could you try fixing your example to be like this?
@app.route("/projects")
async def user_home():
user = await User.all().prefetch_related('roles__project').get()
print(user.roles[0].project.name) #Just a test, but this works here
return await render_template("projects.html", user=user)
That should at least speed up your code by quite a bit, and may be can fix your issue 😄
If it won't work - I would recommend trying serialising model instances to dict before passing to template. There could be some incompatibilities between tortoise models and expected value for template context
@abondar Hey thanks for the quick reply.
I tried the following but now I'm getting a different error before going to Jinja template 'ForeignKeyField' object has no attribute 'name'
user = await User.get(email=session['email']).prefetch_related('roles__project').get()
print(user.roles[0].project.name)
It really is weird.
I called get because it was on your code 😄 , to be honest I'm still learning how this works. But fixing the typo still gave the same error.
Let me try to give more info :
I want a specific user, all its roles and the project of each role.
The error is weird, sounds like it wasn't instantiated properly, maybe my creation code is wrong?
Here is how I create and assign a role/project to an user :
class Project(Model, TimestampMixin):
name = fields.CharField(100)
@classmethod
async def new(cls, name, user):
#Creating the project
project = cls()
project.name = name
await project.save()
#Creating default admin role
role = Role()
role.name = 'Admin'
role.project_id = project.id
await role.save()
await role.users.add(user)
return project
Even printing inside the jinja template works, I still haven't found a solution unfortunately.
I think it could be related to how the for loop in jinja is done.
Edit: It's definitely a mix on how the queryset implemented iterable and how jinja accesses iterables, the following worked :
{% for i in range(user.roles|length) %}
{% set role = user.roles[i] %}
<tr>
<td>{{role.project.name}}</td>
<td>{{role.name}}</td>
</tr>
{% endfor %}
For now this is the fix I'm using but its far from ideal
Did you try serialising model instances to dicts before passing them as context? I think it should work fine, and using serialisation is quite good pattern in general, because it let's you separate data formatting from data storing
Did you try serialising model instances to dicts before passing them as context? I think it should work fine, and using serialisation is quite good pattern in general, because it let's you separate data formatting from data storing
Tortoise-orm models have a serialize method? I couldn't find anything about it in the docs
Sorry, may be I was misleading. I meant some thrid-party serialisers. I, personally, prefer to use https://github.com/marshmallow-code/marshmallow - it's very convenient in use and allows you to declare your desired formatting in code
Sorry, may be I was misleading. I meant some thrid-party serialisers. I, personally, prefer to use https://github.com/marshmallow-code/marshmallow - it's very convenient in use and allows you to declare your desired formatting in code
Never head of marshmallow before but it seems pretty easy to use.
I feel that it adds some redundant processing to use it in an orm though, hopefully tortoise-orm can have its own serializer in the future
We have issue for that #13 , but I don't think that we will be able to attempt it in any near future, because there so much issues that we consider more important
We have a framework almost in place for clean schema extraction.
Then it should be easier to do so properly
Sorry if this is not the right place to ask, but there wasn't even a tortoise-orm tag on stackoverflow.
I can't figure out what's the right syntax to prefetch related data from relationships as I don't want the Jinja template to execute any databate queries
I'm doing the following (In Quart, which is like Flask but async)
And in project.html :
role.project.name
is blank, butrole.name
is working fine.And here are the models :
What am I missing here? I don't understand why it works on the route function but not on the Jinja template