第一步: URLconf 路由管理
- 在 Django 中,定义 URLconf 包括正则表达式、视图两部分 。
- Django 使用正则表达式匹配请求的URL,一旦匹配成功,则调用应用的视图 。
- 注意:只匹配路径部分,即除去域名、参数后的字符串 。
- 在主配置文件中添加子配置文件,使主 urlconf 配置连接到子模块的 urlconf 配置文件 。
主配置文件my2django/urls.py
from django.urls import path, include
urlpatterns = [
#
path('admin/', admin.site.urls),
# ^book以book开头的网址,如何处理呢? 查询bookAPP.urls里面的路由设置
+ path('book/', include('bookApp.urls'))
]
bookApp 子应用的子配置文件:bookApp/urls.py
如下
from django.contrib import admin
from django.urls import path
from django.urls import path, re_path
# .代表当前目录, 从当前目录导入views模块
from . import views
# 路由处理: 当客户端访问网址的时候, 交给哪一个函数去处理客户端的请求并返回响应。
urlpatterns = [
# name='index'是给views.index起的一个别名,便于后续的处理
path('', views.index, name='index'),
# 设计访问书籍详情信息的url地址, 如下:
# http://127.0.0.1:8000/book/1/
# http://127.0.0.1:8000/book/2/
# http://127.0.0.1:8000/book/3/
# Django2中path的路由可以使用正则匹配, Django3中不能, 需要使用re_path
# 正则的规则: [0-9]代表单个数字, \d也代表单个数字, +代表前面的字符出现1次或者多次.
# 正则中的()代表分组,这里将()里面匹配到的内容传递给detail函数.
+ # re_path('([0-9]+)/$', views.detail, name='detail'),
# 注意: int代表整型, id代表将传入的整形数值存储到id变量中,传给视图函数
+ path('<int:id>/', views.detail, name='detail')
]
第二步: 视图函数处理业务逻辑
- 在 Django 中,视图对WEB请求进行回应( response )。
- 视图接收 reqeust 请求对象作为第一个参数,包含了请求的信息 。
- 视图函数就是一个Python函数,被定义在 views.py 中 。
- 定义完成视图后,需要配置 urlconf ,否则无法处理请求。
在视图函数bookApp/views.py
中定义urls文件中函数
from django.shortcuts import render
from django.http import HttpResponse
from .models import Book
# Create your views here.
# 编写第一个视图函数, http协议(基于请求-响应的一个协议, request-response)
def index(request):
return HttpResponse("图书管理系统")
##编写详情函数,从urls获取的id在这里用到
+def detail(request, id):
"""访问书籍详情信息的函数"""
# 从Book书籍表中寻找id=1/2/3(url中需要查询的书籍id)的详细信息
book = Book.objects.get(id=id)
info = """
书籍id: %s
书籍名称: %s
书籍发布日期:%s
""" %(book.id, book.title, book.pub_date)
# 视图函数,传入一个http请求,返回一个http响应
return HttpResponse(info)
测试如图:
等待模板的代码完善后, 再进行测试。
第三步: 模板管理实现好看的HTML页面
作为Web 框架, Django 需要一种很便利的方法以动态地生成HTML。最常见的做法是使用模板。
模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入
(1) 模板引擎配置
- 创建模板的目录如下图
- 修改 BookManage/settings.py 文件,设置 TEMPLATES 的 DIRS 值
(2) 模板语法
- 变量输出语法{{ var }} ##当模版引擎遇到一个变量,将计算这个变量,然后将结果输出。
- 语法{ % tag % } ##作用在输出中创建文本,控制循环或逻辑,加载外部信息到模板中
(3) 主页与详情页前端HTML设计
编辑 view.py 模板
from django.shortcuts import render
from django.http import HttpResponse
from .models import Book
# Create your views here.
# 编写第一个视图函数, http协议(基于请求-响应的一个协议, request-response)
def index(request):
"""书籍管理的首页, 显示所有的书籍信息"""
# 查询数据库中所有的书籍信息
books = Book.objects.all()
# render租用/获取index.html的前端界面, 每次访问前端显示的信息不同, 取决于book书籍的信息
return render(request, 'bookApp/index.html', {'books': books})
# return HttpResponse("图书管理系统")
def detail(request, id):
"""访问书籍详情信息的函数"""
# 从Book书籍表中寻找id=1/2/3(url中需要查询的书籍id)的详细信息
book = Book.objects.get(id=id)
return render(request, 'bookApp/detail.html', {'book': book})
定义 index.html 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书管理系统</title>
</head>
<body>
<ul>
{% for book in books %}
<li><a href="/book/{{ book.id }}/">{{ book.id }}-{{ book.title }}</a></li>
{% endfor %}
</ul>
</body>
</html>
定义 detail.html 模板
在模板中访问对象成员时,都以属性的方式访问,即方法也不能加括号
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书详情页</title>
</head>
<body>
<h1>图书名称: {{ book.title }}</h1>
<h3>图书编号: {{ book.id }}</h3>
<h3>图书发布日期: {{ book.pub_date }}</h3>
<h3>图书人物信息: </h3>
{% if book.hero_set.all %}
<ul>
{% for hero in book.hero_set.all %}
<li>{{ hero.name }}-{{ hero.content }}</li>
{% endfor %}
</ul>
{% else %}
<h6 style="color: mediumvioletred">书籍{{ book.title }}没有人物信息</h6>
{% endif %}
</body>
</html>
测试如图: