Server programming - Django - create web page

Keywords: Database Django Python SQL

Article directory

Foreword ´`

  • In the previous section, we set up the home page. Here we will create some other pages, such as books author, etc
  • This article will help you to learn
    • 1 Application of listview
    • 2. Application of detailview


It's "list view". Don't be surprised by the name. It's the simplest way to build a "routine"
It is to take out all the data in the specified database (class) and display it in the list
For example, baidu is typical

Remember last section we edited the view
Take data from the database like this:

	num_books = Book.objects.all().count()
    num_instances = BookInstance.objects.all().count()
    num_instances_available = BookInstance.objects.filter(status__exact='a').count()
    num_authors = Author.objects.count()  # The 'all()' is implied by default.

Then the context is packed and sent to the template by render to fill in the blank:

context = {
        'num_books': num_books,
        'num_instances': num_instances,
        'num_instances_available': num_instances_available,
        'num_authors': num_authors,
        'num_visits': num_visits,

    # Render the HTML template index.html with the data in the context variable.
    return render(request, 'index.html', context=context)

But last time I used count() for Statistics (how many books and so on)
We're more idiotic here - just dump all the bo ok s out of the database and display them in one column

django encapsulates this kind of stupid view processing, which is Listview
And execute it with the as view() function
The specific operation is very simple
1.catalog/ add:

from django.views import generic

class BookListView(generic.ListView):
    model = Book

BookListView ListView for database Book model

  1. Template edit:
    Create: / locallibrary/catalog/templates/catalog/book_list.html
{% extends "base_generic.html" %}

{% block content %}
    <h1>Book List</h1>

    {% if book_list %}

      {% for book in book_list %}
        <a href="">{{ book.title }}</a> ({{}})
      {% endfor %}

    {% else %}
      <p>There are no books in the library.</p>
    {% endif %}       
{% endblock %}

Of course, don't forget about URL mapping:

urlpatterns = [
    path('', views.index, name='index'),
    path('books/', views.BookListView.as_view(), name='books'),
    path('authors/', views.AuthorListView.as_view(), name='authors'),

We can find out

  • The name of the template Book UU list.html
  • The template variable is the book list variable referenced by {% for book in book list%}

Strange? We never defined how to use it?
This is what ListView does for us. Of course, it is also agreed that the template name and the template variable are model type names + list
class book ->book_list

Detail modification of ListView

In fact, it's a function that takes data from database to view for get queryset
So we can also control the output by modifying this function‘
To achieve this "

  • You can handle the front-end js from the front-end. Of course, you can limit the dynamic output
  • You can also restrict some branch statements (if else) of templates supported by django from the back end
  • It can also reduce data transmission when the database is called at the source
    This is the third way to change get queryset:
class BookListView(generic.ListView):
    model = Book
	paginate_by = 4
    def get_queryset(self):
        return Book.objects.filter(title__icontains='ryan')[:5] # Get 5 books containing the title war

Filter all data records with ryan in title and return to render

In addition, paginate by = 4 limits the maximum number of records displayed in a page
LIMIT BY similar to sql

Then we can run the server:

Edit the details page of each book

We just made a list of books, but we haven't got the details yet
First, modify the book list.html

{% for book in book_list %}
        <a href="{{ book.get_absolute_url }}">{{ book.title }}</a> ({{}})
      {% endfor %}

Mainly the content of hyperlinks is added

Then we boldly add the book's detail page url mapping

urlpatterns = [
    path('', views.index, name='index'),
    path('books/', views.BookListView.as_view(), name='books'),
    path('authors/', views.AuthorListView.as_view(), name='authors'),
    path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
    path('author/<int:pk>', views.AuthorDetailView.as_view(), name='author-detail'),

The author's routine is the same, with the following added:)
Here, it is similar to regular expression to capture all the numbers after author / in url address and store them in pk

If the pattern of the url capture parameter is complex, you are welcome to use the re? Path() function instead of path() and use the re regular expression
This is limited to space. There are many online courses
We can write as follows with repath:

re_path(r'^book/(?P<pk>\d+)$', views.BookDetailView.as_view(), name='book-detail'),

Note that path() doesn't use · regular. Its syntax rules are simple and its function is weak
Re ﹐ u path() is a perfect regular expression


ListView is especially suitable for roughly listing tables, such as application directory menus and so on
However, detailview provides a layout view suitable for "detail page"

Very similar to ListView, you only need to add in catalog/

class BookDetailView(generic.DetailView):
    model = Book

Similarly, book detail is the file name of the template:
But the template variable becomes the model's class name book
Fill in catalog / templates / catalog / book "detail.html:

{% extends "base_generic.html" %}

{% block content %}
  <h1>Title: {{ book.title }}</h1>

  <p><strong>Author:</strong> <a href="">{{ }}</a></p> <!-- author detail link not yet defined -->
  <p><strong>Summary:</strong> {{ book.summary }}</p>
  <p><strong>ISBN:</strong> {{ book.isbn }}</p> 
  <p><strong>Language:</strong> {{ book.language }}</p>  
  <p><strong>Genre:</strong> {% for genre in book.genre.all %} {{ genre }}{% if not forloop.last %}, {% endif %}{% endfor %}</p>  

  <div style="margin-left:20px;margin-top:20px">

    {% for copy in book.bookinstance_set.all %}
    <p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}">{{ copy.get_status_display }}</p>
    {% if copy.status != 'a' %}<p><strong>Due to be returned:</strong> {{copy.due_back}}</p>{% endif %}
    <p><strong>Imprint:</strong> {{copy.imprint}}</p>
    <p class="text-muted"><strong>Id:</strong> {{}}</p>
    {% endfor %}
{% endblock %}

Note "book. Bookinstance" set
First, book and bookinstance are foreign keys and one to many
In this case, we use "one" for more references on the book side, so we use book. Bookinstance ﹐ set, which is wrapped by django

Paging edit

We used to paginate with paginate by = 10, but this only limits the data at the source, but we can't realize the buttons of "previous page", "next page", etc
django encapsulates this
Because almost all of our web pages are like this, we directly change them in base \
Open / locallibrary/catalog/templates/base_generic.html

{% block content %}{% endblock %}
{% block pagination %}
  {% if is_paginated %}
      <div class="pagination">
          <span class="page-links">
              {% if page_obj.has_previous %}
                  <a href="{{ request.path }}?page={{ page_obj.previous_page_number }}">previous</a>
              {% endif %}
              <span class="page-current">
                  Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
              {% if page_obj.has_next %}
                  <a href="{{ request.path }}?page={{ page_obj.next_page_number }}">next</a>
              {% endif %}
  {% endif %}
{% endblock %} 
  • Page obj is a Paginator object. If you use pagination on the current page, such as paginate by = 10, it will start
    This device allows you to get all the information about the current page, the previous page, how many pages, etc.

  • {{request.path}}} can be used to get the current page URL used to create page links.

In addition, we also got the author's by the way:
Template / catalog / author? Detail.html:

{% extends "base_generic.html" %}

{% block content %}
  <h1> {{ author.first_name }}.{{author.last_name}}</h1>
  <p><strong>living:</strong> {{ author.first_name }}.{{ author.last_name }} ({{ author.date_of_birth }}-{{ author.date_of_death }})</p>

  <div style="margin-left:20px;margin-top:20px">
    <h4>What this poor bastard wrote:</h4><ul>
<!-- Reverse lookup here 'many'Quote'One' Not like before 'One'Quote'many' -->
    {% for copy in author.book_set.all %}
      <li><a href=""><{{copy.title}}> ISBN:{{copy.isbn}}</a></li>
    {% endfor %}
{% endblock %}

Template / catalog / author list.html:

{% extends "base_generic.html" %}

{% block content %}
    <h1>Author List</h1>

    {% if author_list %}

      {% for author in author_list %}
        <a href="{{ author.get_absolute_url }}">{{ author.first_name }}.{{ author.last_name }}</a>
      {% endfor %}

    {% else %}
      <p>There are no one.</p>
    {% endif %}
{% endblock %}

catalog/ add

class AuthorListView(generic.ListView):
    model = Author
    paginate_by = 5
class AuthorDetailView(generic.DetailView):
    model = Author

Conclusion ( ̄)  ̄) A kind of

runserver test results
Without accident you will gain:

There are basically a lot of pages here
We'll have a conversation at the next stop

This is another series of learning articles about soft chicken. I hope it can help you

46 original articles published, 52 praised, 30000 visitors+
Private letter follow

Posted by breadcom on Thu, 05 Mar 2020 05:35:10 -0800