4. Creating home page - LiVanych/locallibrary GitHub Wiki
After we defined our models and created some initial library records to work with, it's time to write the code that presents that information to users. The first thing we need to do is determine what information we want to display in our pages, and define the URLs to use for returning those resources. Then we'll create a URL mapper, views, and templates to display the pages.
The URLs that we'll need for our pages are:
catalog/ — The home (index) page.
catalog/books/ — A list of all books.
catalog/authors/ — A list of all authors.
catalog/book/<id> — The detail view for a particular book, with a field primary
key of <id> (the default).
For example, the URL for the third book added to the list
will be /catalog/book/3.
catalog/author/<id> — The detail view for the specific author with a primary key
field of <id>.
For example, the URL for the 11th author added to the list
will be /catalog/author/11.
We created a placeholder file for the URLConf module, named /catalog/urls.py
. Add the following
lines to that file:
urlpatterns = [
path('', views.index, name='index'),
]
A view is a function that processes an HTTP request, fetches the required data from the database,
renders the data in an HTML page using an HTML template, and then returns the generated HTML in
an HTTP response to display the page to the user. The index view follows this model — it fetches
information about the number of Book
, BookInstance
, available BookInstance
and Author
records
that we have in the database, and passes that information to a template for display.
Open catalog/views.py
and note that the file already imports the render()
shortcut function to
generates HTML file using a template and data:
from django.shortcuts import render
# Create your views here.
Paste the following lines at the bottom of the file:
from catalog.models import Book, Author, BookInstance, Genre
def index(request):
"""View function for home page of site."""
# Generate counts of some of the main objects
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()
# Available books (status = 'a')
num_instances_available = BookInstance.objects.filter(
status__exact='a'
).count()
# The 'all()' is implied by default.
num_authors = Author.objects.count()
context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
}
# Render the HTML template index.html with the data
# in the context variable
return render(request, 'index.html', context=context)
Note: Based on your project's settings file, Django will look for templates in a number of places, searching in your installed applications by default. You can find out more about how Django finds templates and what template formats it supports in the Templates section of the Django documentation.
mkdir catalog/templates
vim catalog/templates/base_generic.html
<!DOCTYPE html>
<html lang="en">
<head>
{% block title %}<title>Local Library</title>{% endblock %}
</head>
<body>
{% block sidebar %}
<!-- insert default navigation text for every page -->
{% endblock %}
{% block content %}
<!-- default content text (typically empty) -->
{% endblock %}
</body>
</html>
vim catalog/templates/index.html
{% extends "base_generic.html" %}
{% block content %}
<h1>Local Library Home</h1>
<p>Welcome to LocalLibrary, a website developed by
<em>Mozilla Developer Network</em>!
</p>
{% endblock %}
./manage.py runserver
web http://127.0.0.1:8000 # check how it rendered
Create a new file base_generic.html in /locallibrary/catalog/templates/
and paste the
following code to the file:
<!DOCTYPE html>
<html lang="en">
<head>
{% block title %}<title>Local Library</title>{% endblock %}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous">
<!-- Add additional CSS in static file -->
{% load static %}
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-sm-2">
{% block sidebar %}
<ul class="sidebar-nav">
<li><a href="{% url 'index' %}">Home</a></li>
<li><a href="">All books</a></li>
<li><a href="">All authors</a></li>
</ul>
{% endblock %}
</div>
<div class="col-sm-10 ">{% block content %}{% endblock %}</div>
</div>
</div>
</body>
</html>
The base template also references a local css file (styles.css
) that provides additional styling.
Create a styles.css
file in /locallibrary/catalog/static/css/
and paste the following code in the file:
.sidebar-nav {
margin-top: 20px;
padding: 0;
list-style: none;
}
Create a new HTML file index.html
in /locallibrary/catalog/templates/
and paste the following code in
the file. This code extends our base template on the first line, and then replaces the default content
block for the template.
{% extends "base_generic.html" %}
{% block content %}
<h1>Local Library Home</h1>
<p>Welcome to LocalLibrary, a website developed by
<em>Mozilla Developer Network</em>!
</p>
<h2>Dynamic content</h2>
<p>The library has the following record counts:</p>
<ul>
<li><strong>Books:</strong> {{ num_books }}</li>
<li><strong>Copies:</strong> {{ num_instances }}</li>
<li><strong>Copies available:</strong> {{ num_instances_available }}</li>
<li><strong>Authors:</strong> {{ num_authors }}</li>
</ul>
<!-- Add image as static file -->
{% load static %}
<img src="{% static 'images/local_library_model_uml.png' %}"
alt="UML diagram" style="width:555px;height:540px;">
{% endblock %}
For more information on working with static files see Managing static files in the Django documentation.
You need to point Django to search for your templates in the templates folder. To do that, add the
templates dir to the TEMPLATES
object by editing the settings.py
file as shown in bold in the
following code sample:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Writing your first Django app, part 3: Views and Templates (Django docs)
URL dispatcher (Django docs)
View functions (DJango docs)
Templates (Django docs)
Managing static files (Django docs)
Django shortcut functions (Django docs)