服务端编程(十)- Django -创建网站页面

Gytha ·
更新时间:2024-11-13
· 504 次阅读

文章目录前言 ´・ᴗ・`ListviewListView 的细节修改编辑每本书的详情页detailView分页的编辑结语( ̄︶ ̄)↗ 前言 ´・ᴗ・` 上一节我们建立了主页 这里我们来创建一些别的网页 比如关于books author等等 本篇内容将会帮助你学习… 1 ListView的应用 2 DetailView的应用 Listview

就是 “列表视图” 别被名字吓到了 这是最简单的视图构建“套路”
就是在指定的数据库(类)中取出所有数据 然后列表显示出来
比如像百度那种就是典型的
在这里插入图片描述
还记得上节 我们是编辑过view的
像这样从数据库取数据:

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.

然后 context打包 通过render送到template那边去填空:

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)

不过上次有点不同 需要统计数据(多少本书什么的) 用了count()
这里 我们更加傻瓜化——直接把数据库所有书倒出来 然后一列显示就ok了

django给我们封装了这种傻瓜化的view处理 就是Listview
而且用as_view() 函数来执行
具体操作很简单
1.catalog/view.py 添加:

from django.views import generic class BookListView(generic.ListView): model = Book

BookListView 针对数据库Book模型的ListView

模板编辑:
创建: /locallibrary/catalog/templates/catalog/book_list.html {% extends "base_generic.html" %} {% block content %}

Book List

{% if book_list %} {% else %}

There are no books in the library.

{% endif %} {% endblock %}

当然 URL映射别忘了:

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

我们可以发现

模板的名字 book_list.html 模板变量 就是那个{% for book in book_list %} 引用的book_list 这个变量

奇怪不?我们从来没定义过 怎么就能用了呢?
这就是ListView帮我们干的事 当然也约定 模板名字与模板变量都采用model那个类的名字+list
class book ->book_list

ListView 的细节修改

事实上 是一个函数为get queryset 做了 从数据库拿数据到view的工作
因此 我们通过修改这个函数 自然也可以控制输出的结果
实现这点 ’

可以从前端搞定 前端js当然可以限制 动态输出 也可以后端限制 通过django支持的模板的一些分支语句(if else) 还可以源头上 数据库调用的时候就减少数据传输
这里更改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

筛选所有title包含ryan的数据记录 然后返回给render

另外 paginate_by = 4 限制了一页中显示最大的记录条数
类似sql的LIMIT BY

然后这里我们就可以runserver一下啦:
在这里插入图片描述

编辑每本书的详情页

我们只是作了个书的清单 但是详情页还没弄
这里 先把book_list.html 修改一下

{% for book in book_list %}
  • {{ book.title }} ({{book.author}})
  • {% endfor %}

    主要是超链接的内容加上了

    然后我们大胆的添加书本的详情页 url映射

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

    author的套路相同 一并添加了:)
    这里 就类似正则表达式 捕获url地址中 author/ 后面所有的数字 并且存到pk这个变量里面

    如果url捕获参数的模式(pattern) 很复杂 欢迎使用re_path() 函数代替path() 并且使用re正则表达式
    这里限于篇幅不讲了 网上有关教程很多
    我们应用repath 可以这么写:

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

    注意path()不采用·正则 其语法规则很简单 功能很弱
    re_path()是完全用正则表达式的 功能无敌强

    detailView

    ListView特别适合 大致列个表 这种应用 目录菜单什么的
    然而detailview提供一个适合“详情页”的布局视图

    非常类似ListView 你只需在catalog/view.py 中添加:

    class BookDetailView(generic.DetailView): model = Book

    同样 book_detail 作为模板的文件名称:
    不过模板变量变成model的类名 book
    在catalog/templates/catalog/book_detail.html 填写:

    {% extends "base_generic.html" %} {% block content %}

    Title: {{ book.title }}

    Author: {{ book.author }}

    Summary: {{ book.summary }}

    ISBN: {{ book.isbn }}

    Language: {{ book.language }}

    Genre: {% for genre in book.genre.all %} {{ genre }}{% if not forloop.last %}, {% endif %}{% endfor %}

    Copies

    {% for copy in book.bookinstance_set.all %}

    {{ copy.get_status_display }}

    {% if copy.status != 'a' %}

    Due to be returned: {{copy.due_back}}

    {% endif %}

    Imprint: {{copy.imprint}}

    Id: {{copy.id}}

    {% endfor %}
    {% endblock %}

    注意“book.bookinstance_set”
    首先 book 与 bookinstance 是外键 而且是一对多的
    我们这里在book这端 用“一”引用多 就用了book.bookinstance_set 这是django给我们封装好的

    分页的编辑

    我们之前通过paginate_by = 10 进行分页 但这只是源头上限制了数据 但不能实现“前一页”“后一页”的按钮等
    django封装了这个
    由于我们几乎所有网页都这样式 我们直接在base_generic 更改:
    打开 /locallibrary/catalog/templates/base_generic.html

    {% block content %}{% endblock %} {% block pagination %} {% if is_paginated %} {% endif %} {% endblock %}

    page_obj 是一个 Paginator 对象,如果在当前页面上使用分页 如paginate_by = 10 ,它将启动
    这玩意允许您获取有关当前页面,之前页面,有多少页面等的所有信息。

    {{ request.path }}可用来获取用于创建分页链接的当前页面URL

    另外 我们顺便把author的也弄了:
    模板 template/catalog/author_detail.html:

    {% extends "base_generic.html" %} {% block content %}

    {{ author.first_name }}.{{author.last_name}}

    living: {{ author.first_name }}.{{ author.last_name }} ({{ author.date_of_birth }}-{{ author.date_of_death }})

    What this poor bastard wrote:

    {% endblock %}

    模板 template/catalog/author_list.html:

    {% extends "base_generic.html" %} {% block content %}

    Author List

    {% if author_list %} {% else %}

    There are no one.

    {% endif %} {% endblock %}

    catalog/view.py 添加

    class AuthorListView(generic.ListView): model = Author paginate_by = 5 class AuthorDetailView(generic.DetailView): model = Author 结语( ̄︶ ̄)↗

    runserver检验战果
    不出意外 你将收获:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    到这里 基本上很多页面都能搞定了
    下一站 我们会聊聊 会话

    这是软菜鸡的其他系列学习文章 希望能够帮到你 ( •̀ ω •́ )✧

    想学习数据库嘛? 不妨从MySQL入手
    MySQL专栏

    python这么火 想要深入学习python 玩一下简单的应用嘛?可以看我专栏 还在持续更新中哦:
    python应用

    这是本服务端编程专栏
    手把手带你学服务端

    谢谢大佬支持!


    作者:阮菜鸡



    建网站 服务端 Django

    需要 登录 后方可回复, 如果你还没有账号请 注册新账号