4. Creating home page - LiVanych/locallibrary GitHub Wiki

Read the original article

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. Basics Django

Defining the resource URLs

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.

Creating the index page

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'),
]

View (function-based)

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)

Template

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

The LocalLibrary base template

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;
}

The index template

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.

Configuring where to find the templates

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',
            ],
        },
    },
]

See also

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)

Full version of the original article on MDN site

⚠️ **GitHub.com Fallback** ⚠️