Django — Step 10

Brian Mayrose
5 min readJul 18, 2019

--

Displaying Data From The Database In Our Templates

Let’s start with the display_1 app.

Open the views.py file in the display_1 app directory:

from django.shortcuts import renderdef index(request):
return render(request, 'display_1/index.html')
def display_1_item(request):
return render(request, 'display_1/display_1_item.html')

The concept here is that we will fetch data from the database model, then insert the data into the template displaying it to the client. Here is a link to the official documentation:

To do this we need to first import item from .models at the top of views.py.

Inside the index definition, we need to define a variable called items to item.object.all(). Calling item.object.all() grabs all of the items from the database.

Then we define a context dictionary containing the item object and we pass context into the return render() method:

from django.shortcuts import render
from .models import item
def index(request):
items = item.object.all()
context = {
'items': items
}
return render(request, 'display_1/index.html', context)
def display_1_item(request):
return render(request, 'display_1/display_1_item.html')

Then we pass a python dictionary defined as the variable context into the render() method as another argument.

from django.shortcuts import render
from .models import item
def index(request):
dbitems = item.objects.all()
context = {'dbitems': dbitems }
return render(request, 'display_1/index.html', context)
def display_1_item(request):
return render(request, 'display_1/display_1_item.html')

Now we can go to the template display_1/index.html and start entering the Jinja if blocks that will loop through the items in the database:

{% if dbitems %}
{% for i in dbitems %}
{% endfor %}
{% else %}
<div class="col-md-12">
<p>No items Available</p>
</div>
{% endif %}

The first Jinja tag, {% if dbitems %}, checks to see if there are any items by referencing the dbitems variable we added to the display_1 index view.

{% if dbitems %}

The second Jinja block, {% for i in dbitems %} and {% endfor %}, located inside the if block, iterates over the items found in the database.

{% for i in dbitems %}{% endfor %}

If no items are found in the database, the jinja tag {% else %} defines what will happen. If there are no listings available, in this case, we are just displaying a message explaining there are no listings:

{% else %}
<div class="col-md-12">
<p>No items Available</p>
</div>

I deleted all the origional HTML we created in the content block of the display_1/index.html file earlier and replaced it with:

{% block content %}<body class="display_body">
<section>
<h1 class="display-4 mb-4 text-center">
Section 1
</h1>
<div class="container text-center"> {% if dbitems %}
{% for i in dbitems %}
<div class="box_1">
<img class="card-img-top" src="{{ i.photo_main.url }}" alt="">
<h2>{{ i.title }}</h2>
<p>{{ i.description_1 }}</p>
</div>
{% endfor %}
{% else %}
<div class="col-md-12">
<p>No items Available</p>
</div>
{% endif %}
</div>
</section>
</body>
{% endblock %}

Instead of hardcoded content, we can now use Jinja variables that call and loop over the specific details from the database model item.

The jinja variables have double curly braces but do not use the percentage symbols, for example {{ i.title }} is what we put to retrieve the title of an item. we call the singular variable declared in the for loop, followed by the element of the model we want.

Let's open the display_1/static/css/display_1_index.css file and add some simple style to the displayed items:

.container{
display: flex;
flex-wrap: wrap;
}
.display_body{
background-color: #aaaaff;
}
.box_1{
background-color: rgba(255, 255, 255, 0.5);
height: auto;
width: 300px;
margin: 5px;
padding: 5px;
padding-bottom: 5px;
border-radius: 7px;
}

We implemented the flex property on the container and added some padding and margins to our items.

More on CSS flex here:

Don’t forget to run the collectstatic command after saving your css:

python manage.py collectstatic

I also added 3 more items from the admin panel in order to see how the items are arranged. Save your files and reload the server:

We can also show items from the database in an order based on upload date.

This can be useful if you want to show the most recent additions first.

Very simply, we just need to edit the dbitems definition in our index definition in display_1/views.py.

Append .order_by(‘-list_date’) to the end of the dbitems definition after the .all() function:

def index(request):
dbitems = item.objects.all().order_by('-list_date')
context = {'dbitems': dbitems }
return render(request, 'display_1/index.html', context)

The use of a hyphen reverses the order of items being displayed, showing the most recently added item first:

Another important addition we should make to our index view is to add a filter that will stop Django from displaying and items marked as ‘not published’.

Just like the orde_by function, we append a filter function to the end of the dbitems definition. The filter function receives the is_published=True argument:

def index(request):
dbitems = item.objects.all().order_by('- list_date').filter(is_published=True)
context = {'dbitems': dbitems }
return render(request, 'display_1/index.html', context)

Now from the admin panel, you can check or uncheck the ‘is published’ box and the listing will be shown based on that choice:

Unpublished Item 5
Item 5 is not shown

Now that we are displaying the items from our database, we should add a pagination feature so that Django will automatically divide our content into separate pages when we start accumulating more and more items.

--

--