Cannot render views in template in Django

Viewed 527

I cannot render my views in templates. I think I've tried everything. everything works except data rendering on template.

My model.py:

from django.db import models
class Driver(models.Model):
    name = models.CharField(max_length=150)
    surname = models.CharField(max_length=150, default='')

    def __str__(self):
        return self.name

My views.py:

from django.shortcuts import render
from zoo.models import Driver


def MyView(request):
    drivers = Driver.objects.all()
    return render("zoo/base.html", {"drivers": drivers})

My template:

{% load staticfiles %}
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Example</title>
    {% render_bundle 'app' 'css' %}
  </head>
  <body>
     {{ drivers }}

     {{ drivers.name }}

     {% for driver in drivers %}
         {{driver.name}}

</body>
</html>

My database got 315 drivers, contains names and surnames for drivers.

Project structure:

Project 
      app
         setting.py
         __init__.py
          ...
      zoo
         templates
              base.html
         __init__.py
         models.py
         views.py
          ...
2 Answers

views.py

In views.py change:

return render("zoo/base.html", {"drivers": drivers})

to:

return render(request, "zoo/base.html", {"drivers": drivers})

template

You need to close your for loop in your template. There's good information on this worth reading at https://docs.djangoproject.com/en/3.1/ref/templates/builtins/.

{% for driver in drivers %}
    {{ driver.name }}
{% endfor %}

Also I'm guessing from the code you provided and your explanation that {{ drivers.name }} probably won't render. It won't be until you iterate through your drivers QuerySet that you'll be able to access the individual driver fields (like driver.name).

File Structure

It's best practice to namespace your templates and staticfiles. Django's tutorial talks about this at https://docs.djangoproject.com/en/3.1/intro/tutorial03/. If you do this your directory structure will change from this (what you currently have):

Project 
      app
         setting.py
         __init__.py
          ...
      zoo
         templates
              base.html
         __init__.py
         models.py
         views.py
          ...

to this:

Project 
      app
         setting.py
         __init__.py
          ...
      zoo
         templates
            zoo
               base.html
         __init__.py
         models.py
         views.py
          ...

Lastly, I strongly recommend you rename your template to something specific to this particular view. If this is your index view, for example, you could name it index.html. Or perhaps zoo.html to correspond with the name of your view.

This isn't necessary but it will be useful down the road as you build this app out if you want extend a base.html file. This is handy because it allows you to cut down on your boilerplate html and just focus on the core functionality of each template/view. It also has the advantage of making it easier to provide a consistent user experience between different pages that all extend the same base.html file.

To learn more about this check out https://docs.djangoproject.com/en/3.1/ref/templates/language/.

Important Note: If you do this, don't forget to change your call to render in views.py to accomodate your renamed template file.

This:

return render("zoo/base.html", {"drivers": drivers})

Should be this:

return render(request, "zoo/base.html", {"drivers": drivers})
Related