How to make Django template variables work async?
I'm trying to apply Async approach to an existing Django project, updating views appears this error: django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
views.py
@sync_to_async
def get_educations():
return Education.objects.filter(highlight=True).order_by("-order")
async def home(request):
return render(request, "home.html", {
"educations": await get_educations(),
})
home.html
<section class="d-flex flex-column">
<h3 class="section">Education</h3>
{% for education in educations %}
{% include "preview_education.html" %}
{% endfor %}
Trying with return [Education.objects.first()]
works well.
Any idea how to solve it ?
The solutions is to cast Django Queryset to list and use select_related
with the model relations.
views.py:
@sync_to_async
def get_educations():
return list(
Education.objects.filter(
highlight=True
)
.select_related('organization')
.order_by("-order")
)
async def home(request):
return render(request, "home.html", {
"educations": await get_educations()
}
home.html:
<section class="d-flex flex-column">
<h3 class="section">Education</h3>
{% for education in educations %}
<article class="element">
<h4>{{ education.name }}</h4>
<p>{{ education.organization }}</p>
<p>{{ education.place }}</p>
<p>{{ education.duration }}</p>
</article>
{% endfor %}
</section>