Leszek Wroński Leszek Wroński - 24 days ago 7
Python Question

Django: 'Could not parse' error when creating an HTML list of names of objects from a database

I'm trying to create a website for students and professors which includes a database of courses. Each course is a model Kurs which includes among other fields the following ones, which are the professor running the course and the name of the course:

prowadzacy = models.ForeignKey(User)
nazwa = models.CharField(max_length=200)


In the shell, I can easily find all courses ran by a given professor:

>>> Kurs.objects.filter(prowadzacy__username='stefantestowy')
<QuerySet [<Kurs: Estetyka 7>]>


So in the above I learn that the professor with the username 'stefantestowy' runs one course, 'Estetyka 7'.

After a professor logs in (I'm using the built-in Django login mechanism) he or she is redirected to usersite.html, which should display information about the professor, including the list of names of the courses he or she is running. But if I want to crudely use the syntax which works in the shell to produce an HTML list, I encounter a 'cannot parse' error. Namely, my usersite.html contains the following:

Your login is {{request.user.username}} </br>

Your name is {{request.user.first_name}} {{request.user.last_name}} </br>

(...)

Here is a list of your courses: </br>
<ul>
{% for kurs in Kurs.objects.filter(prowadzacy__username=request.user.username) %}
<li>{{ kurs.nazwa }}</li>
{% endfor %}
</ul>


which leads to the following error:

Could not parse the remainder: '(prowadzacy__username=request.user.username)' from 'Kurs.objects.filter(prowadzacy__username=request.user.username)'


Just to be sure, I changed

prowadzacy__username=request.user.username


to

prowadzacy__username='stefantestowy'


that is, the name successfully used in the shell, but the 'could not parse' error persists. What am I doing wrong?

Additional detail, if it could be of any help: settings.py contains

LOGIN_REDIRECT_URL = '/polls/usersite'


urls.py's urlpatterns contains

url(r'^usersite/$', views.userviewbasic, name='usersite'),


and the relevant view in views.py is just the minimal

def userviewbasic(request):
return render(request, 'polls/usersite.html')


Thanks in advance!

Answer
{% for kurs in   Kurs.objects.filter(prowadzacy__username=request.user.username) %}
    <li>{{ kurs.nazwa }}</li>
{% endfor %}

This won't work in a template.

You will need to pass the filtered list to the template like so.

def userviewbasic(request):
    kurs = Kurs.objects.filter(prowadzacy__username=request.user.username)
    return render(request, 'polls/usersite.html', {"kurs": kurs})

And iterate over the parameter kurs in the template.

{% for kur in kurs %}
    <li>{{ kur.nazwa }}</li>
{% endfor %}

You can read more about the template language in Django here: https://docs.djangoproject.com/en/1.10/ref/templates/api/#rendering-a-context