- 1. 初探 Django
- 2. Django 视图与网址
- 3. Django 模板
- 4. Django 模型
- 1. 认识数据库
- 2. Django 中的数据库
- 3. 同步数据库
- 4. 利用 admin 后台系统管理数据
- 5. admin 后台系统管理
- 6. 修改 models.py
- 7. 设计博文模型
- 8. Django 中可用的各类模型
- 9. 设计博文模型——简易版
- 10. 设计博文模型——进阶版
- 11. 博文基础模型
- 12. 关联作者模型
- 13. 新建分类模型和标签模型
- 14. 关联分类和标签模型
- 15. 一对多
- 16. 多对多
- 17. 运行 Django 管理命令
- 18. 完成 makemigrations
- 19. 运行 Django 管理命令
- 20. 重新运行 Django 服务器
- 21. 向 admin 后台添加模型
- 22. 添加 Category
- 23. 从数据库中提取真正的博文信息
- 24. 设计博客详情页网址
- 25. 修改博客首页的详情页链接
- 26. 修改 urls.py
- 27. 修改 views.py
- 28. 添加博客详情页模板
- 29. 修改 post.html 为模板格式
- 30. 更漂亮的排版
- 31. 安装 markdown 模块
- 32. 页面渲染情况
- 33. 添加 safe 标签
- 34. 调整 url
1. 初探 Django
1. Why Django?
- 免费开源
- 功能丰富
- 开发迅速
- 可扩展性强
- 模版系统
- 后台管理
2. 新建 Python 虚拟环境
- 在桌面新建项目文件夹,比如名为 website
- 在命令行里利用 cd 命令进入到 website 文件夹
- 输入
python3 -m venv djangoenv
- 在 website 文件夹内会出现一个 djangoenv 文件夹
- Windows 用户继续输入
djangoenv\Scripts\activate
- Mac 用户继续输入
source djangoenv/bin/activate
命令行开头会出现( djangoenv )字样,如图:
- 导出项目依赖
pip freeze > requirements.txt
#使用
pip install -r requirements.txt
在命令行里输入
pip3 install django
Mac 在虚拟环境之中,直接输入 python 就是 python3 的版本。
3. 安装 Django 并新建项目
安装完成输入
django-admin startproject my_blog .
# django-admin.py startproject my_blog
其中 my_blog 是 Django 网站项目名称,根据自己需求更改
注意:不要取 django 或者test之类容易产生冲突的名称
然后就会在 website 文件夹中出现 my_blog 文件夹
里面内容如图
4. 初始化生成文件用途
文件名称 | 用途 |
---|---|
manage.py | 一个在命令行中可以调用的网站管理工具 |
在 my_blog 文件夹里: | |
init.py | 告诉 Python 这个文件夹是一个模块 |
settings.py | my_blog 项目的一些配置 |
urls.py | 网站内的各个网址声明 |
wsgi.py | web 服务器与 Django 项目的接口 |
5. 检测 Django 项目是否安装成功
在命令行里输入
python3 manage.py runserver
6. 检测 Django 项目是否安装成功
在浏览器中输入网址:127.0.0.1:8000
7. 在命令行中快速用 cd 打开文件夹
在命令行中输入 cd+空格 然后将文件夹拖进来
8. 学习资源
- MDN
链接:https://developer.mozilla.org/zh-CN/docs/Learn
- 配色参考
链接:https://coolors.co/palettes/trending
9. 作业
创建一个 Django 网站及你的博客首页,在自己电脑上搭建一个 Django 项目,制作一个网站首页页面。
2. Django 视图与网址
1. python manage.py migrate
前面我们运行 Django 的时候,命令行提示我们如下内容:
您有18个未应用的迁移。你的项目可能不会正常工作,直到你应用程序的迁移: admin, auth, contenttype, session。
运行 “python manager.py migrate” 来应用它们。
你可以理解为创建数据库,一帮我们在做这种比较完善的项目的时候,它的提示一般是比较全的。所以,有时候你翻译一下就知道要做什么事情。
2. 新建一个 Django App
在命令行中进入到 Django 项目文件夹下,也就是和 manage.py
同一个路径:
python3 manage.py startapp blog
完成后多出来一个 blog 文件夹,内容如下
App 的作用:
比如一个网站留言板块功能是一个 App,或者是用户登陆功能,这样也是一个 App。而这个 App 是可以注册的,注册之后网站就可以使用了。也就是把这个 App 拷贝到其他的 Django 网站也是可以直接使用的。
这里目前只是创建了 App 我们还未注册到网站之中,所以我们需要注册到网站之中。
3. 将 App 添加到 settings.py 里
在 Django 项目文件夹中有一个和当前项目同名的文件夹,里面有一个 settings.py 文件,在 INSTALLED_APPS 里添加一个 blog 项目
4. Django 的 MTV 模式
- Browser:浏览器
- URL:网址
- View:视图
- Model :模型
- Database:数据库
- Template:模板
5. 编写视图函数
打开 blog/views.py 文件
默认界面如下
6. 编写 views.py
添加如下语句
from django.shortcuts import render
from django.http import HttpResponse # 从 django 的 http 模块引入 HttpResponse 函数
# from 某某模块的某某子模块 import 某个函数
def index(request):
# 定义一个 index 函数处理主页的访问请求 Request 包含了用户浏览器传来的 HTTP 请求内容
return HttpResponse("欢迎来到 AI悦创博客!") # 用 HttpResponse 函数直接返回一段文字给用户
7. 创建 urls.py
在 blog 文件夹下创建一个新的文件,保存为 urls.py 「这里的 bolg 就是我们上面创建的 App」
用于处理网址的解析
填入以下内容
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
# path(route, view)
# path(route, view, name="'index'")
]
# 单词 route
"""
n. 路线,航线;道路,公路;(交通工具的)固定路线;巡访;途径,渠道;(北美)递送路线;用于美国干线公路号码前
v. 按特定路线发送,为……规定路线
"""
8. 注意!
在 my_blog 文件夹下本来就有 urls.py 文件 和我们刚刚创建的 urls.py 不是同一个
9. 配置项目的 urls.py
打开 my_blog 文件夹里的 urls.py,看到如下内容
10. 默认存在一个 admin 网址
在命令行运行
python3 manage.py runserver
然后在浏览器打开网址: 127.0.0.1:8000/admin
11. 创建一个管理员账号
在命令行中输入下面内容
python manage.py createsuperuser
12. 用管理员账户登录后台
在命令行运行
python manage.py runserver
然后在浏览器打开网址: 127.0.0.1:8000/admin
如果你的服务没有关闭,你可以刷新页面,访问本地链接。admin 链接,进行登录。
当然,我们也可以在后台创建用户,这是完全没有问题的。
13. 配置项目的 urls.py
修改 my_blog 文件夹里的 urls.py
添加两处内容
from django.contrib import admin
from django.urls import path, include # 添加一个 include
urlpatterns = [
path('admin/', admin.site.urls), # 这个就是你在浏览器中输入的 url
path('blog/', include('blog.urls'), name='aiyc'), # 地址结尾需要添加 /
]
这个时候你的主页链接变成了:http://127.0.0.1:8000/blog/ 直接访问:http://127.0.0.1:8000/ 会出现如下页面:
以上页面默认是开启 DEBUG = True
才显示的,如果你关闭了则和下面页面类似:
14. 如果修改 urls.py
如果修改 blog 里 urls.py 的网址会发生什么
原本现在的代码:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index')
# path(route, view, name="'index'")
]
修改之后的代码:
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.index, name='index')
# path(route, view, name="'index'")
]
这个时候,你访问 blog 页面就不能直接 blog 访问,还需要加上 index,也就是此链接:http://127.0.0.1:8000/blog/index/
如果这个时候,blog app 里面又加了一行代码:path('', views.index, name='index')
则如果 http://127.0.0.1:8000/blog/ 后面什么都不接上,那就使用该新增的语句。如果是接了则查找匹配的。比如 index,则匹配 index 包含的页面 view 。
15. 更复杂的网址处理
修改 blog 文件夹里的 urls.py 添加一行:
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.index, name='index'),
# path(route, view, name="'index'")
path('<int:blog_id>', views.blog_detail, name='blog_detail')
]
16. 在 views.py 添加函数
from django.shortcuts import render
from django.http import HttpResponse # 从 django 的 http 模块引入 HttpResponse 函数
# from 某某模块的某某子模块 import 某个函数
def index(request):
# 定义一个 index 函数处理主页的访问请求 Request 包含了用户浏览器传来的 HTTP 请求内容
return HttpResponse("欢迎来到 AI悦创博客!") # 用 HttpResponse 函数直接返回一段文字给用户
def blog_detail(request, blog_id):
return HttpResponse("这是第「{}」篇博客".format(blog_id))
17. 通过网址实现一个加法器
如果我们想要通过 /blog/123/456 这样的网址实现一个加法器, 得到 123+456 的结果,该如何设计 urls.py
- Blog 中的 urls.py
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.index, name='index'),
# path(route, view, name="'index'")
path('<int:blog_id>', views.blog_detail, name='blog_detail'),
path('<int:blog_id1>/<int:blog_id2>', views.blog_sum, name='blog_sum'),
]
- Blog 中的 views.py
from django.shortcuts import render
from django.http import HttpResponse # 从 django 的 http 模块引入 HttpResponse 函数
# from 某某模块的某某子模块 import 某个函数
def index(request):
# 定义一个 index 函数处理主页的访问请求 Request 包含了用户浏览器传来的 HTTP 请求内容
return HttpResponse("欢迎来到 AI悦创博客!") # 用 HttpResponse 函数直接返回一段文字给用户
def blog_detail(request, blog_id):
return HttpResponse("这是第「{}」篇博客".format(blog_id))
def blog_sum(request, blog_id1, blog_id2):
return HttpResponse("Result:{blog_id1} + {blog_id2} = {result_sum}".format(blog_id1=blog_id1, blog_id2=blog_id2, result_sum=blog_id1 + blog_id2))
更多参考链接:https://docs.djangoproject.com/zh-hans/3.1/topics/http/urls/
系统讲解:
例如
下面是一个简单的 URLconf:
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
注意:
- 要从 URL 中取值,使用尖括号。
- 捕获的值可以选择性地包含转换器类型。比如,使用
<int:name>
来捕获整型参数。如果不包含转换器,则会匹配除了/
外的任何字符。 - 这里不需要添加反斜杠,因为每个 URL 都有。比如,应该是
articles
而不是/articles
。
一些请求的例子:
/articles/2005/03/
会匹配 URL 列表中的第三项。Django 会调用函数views.month_archive(request, year=2005, month=3)
。/articles/2003/
would match the first pattern in the list, not the second one, because the patterns are tested in order, and the first one is the first test to pass. Feel free to exploit the ordering to insert special cases like this. Here, Django would call the functionviews.special_case_2003(request)
/articles/2003
would not match any of these patterns, because each pattern requires that the URL end with a slash./articles/2003/03/building-a-django-site/
会匹配 URL 列表中的最后一项。Django 会调用函数views.article_detail(request, year=2003, month=3, slug="building-a-django-site")
。
路径转换器
下面的路径转换器在默认情况下是有效的:
str
- 匹配除了'/'
之外的非空字符串。如果表达式内不包含转换器,则会默认匹配字符串。int
- 匹配 0 或任何正整数。返回一个int
。slug
- 匹配任意由 ASCII 字母或数字以及连字符和下划线组成的短标签。比如,building-your-1st-django-site
。uuid
- 匹配一个格式化的 UUID 。为了防止多个 URL 映射到同一个页面,必须包含破折号并且字符都为小写。比如,075194d3-6885-417e-a8a8-6c931e272f00
。返回一个UUID
实例。path
- 匹配非空字段,包括路径分隔符'/'
。它允许你匹配完整的 URL 路径而不是像str
那样匹配 URL 的一部分。
18. 整体逻辑图
我们到这里就直接使用了如下流程:
之后我们添加个模版,这样使得我们的网站更加美观。
19. 作业
创建一个 Blog App ,能处理博客首页的访问请求,能处理不同的博客数字 id。
3. Django 模板
1. 建立 templates 文件夹
在 blog 文件夹中新建一个 templates 文件夹,结构如下
2. 添加博客首页 HTML
在刚才新建的 templates 文件夹中新建一个 blog_index.html 文件, blog_index.html 中填写简单的首页欢迎内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>AI悦创博客</title>
<meta name="description" content="">
<meta name="keywords" content="">
</head>
<body>
<h1>欢迎来到AI悦创博客首页</h1>
<p id="welcome-line">欢迎来到AI悦创教育</p>
<a class="link" href="https://www.aiyc.top">AII悦创</a>
<a class="link" href="https://www.aiyc.top/python3spiderlearn">Python爬虫系统教程</a>
<ol>
<li>Python</li>
<li>Java</li>
<li>C++</li>
</ol>
</body>
</html>
目标:输入 127.0.0.1:8000/blog/ 网址后打开下面的 HTML ,上一节课我们使用 view 直接返回结果,这节课我们使用 view 去使用我们的 templates 。
3. 修改 views.py
原本的内容:
def index(request):
# 定义一个 index 函数处理主页的访问请求 Request 包含了用户浏览器传来的 HTTP 请求内容
return HttpResponse("欢迎来到 AI悦创博客!") # 用 HttpResponse 函数直接返回一段文字给用户
修改为:
def index(request):
return render(request, 'blog_index.html')
4. 运行 Django 服务器
在命令行运行
python manage.py runserver
然后在浏览器打开网址:http://localhost:8000/blog/index/
5. 理解一下模板系统
在 views.py 中指定渲染某个模板
Django 会自动搜寻各个 App 的 templates 文件夹,然后在 blog/templates/blog_index.html
6. 问题?
不同的 App 中可能存在同名的 html 文件,容易产生冲突怎么办?
7. 解决方案
在 templates 文件夹中再建立和当前 App 同名的文件夹,html 文件放到该文件夹中。
即原来是:blog/templates/blog_index.html
改成:blog/templates/blog/blog_index.html
修改 views.py 内容为
def index(request):
return render(request, 'blog/blog_index.html')
8. Django 模板进阶
1. 强大的模板系统
比方说我希望我们的数据不要写在 HTML 文件当中,就相当于我们的 HTML 相当于填空「类似考试试卷那种」,答案使用 view 来填。
修改 blog_index.html 文件
2. 修改 views.py
添加如下语句:
启动服务之后,即可访问该页面:
3. 渲染列表
views.py 中添加如下语句
def index(request):
language_list = ['Python', 'Java', 'C++', 'JavaScript', 'C', 'C#']
return render(request, 'blog/blog_index.html',
{"title": "欢迎来到AI悦创的博客站点", 'language_list': language_list})
4. 循环语句
修改 blog_index.html 文件
刷新页面之后的结果:
5. 获取循环数字
<!-- --snip-- -->
<ol>
{% for item in language_list %}
<li>{{forloop.counter}}---{{item}}</li>
{% endfor %}
</ol>
6. 渲染字典
修改 blog_index.html 文件
7. 模板中的条件判断
views.py 中添加如下语句
修改 blog_index.html 文件
elif, else, and, or 等关键词都可以使用
8. 判断用户是否登录
9. 使用现成的博客模板
10. index.html
原本代码:
def index(request):
language_list = ['Python', 'Java', 'C++', 'JavaScript', 'C', 'C#']
link_dict = {'AI悦创博客': 'https://www.aiyc.top', 'FP创客空间': 'https://www.fpmakerspace.com'}
flag = False
return render(request, 'blog/blog_index.html',
{
"title": "欢迎来到AI悦创的博客站点",
"language_list": language_list,
"link_dict": link_dict,
"flag": flag,
})
修改之后:
def index(request):
language_list = ['Python', 'Java', 'C++', 'JavaScript', 'C', 'C#']
link_dict = {'AI悦创博客': 'https://www.aiyc.top', 'FP创客空间': 'https://www.fpmakerspace.com'}
flag = False
return render(request, 'blog/index.html',
{
"title": "欢迎来到AI悦创的博客站点",
"language_list": language_list,
"link_dict": link_dict,
"flag": flag,
})
11. 打开 127.0.0.1:8000/blog/index
样式出问题,没有找到CSS,JS,图片等素材
12. 拷贝素材
把素材拷贝到项目里来
在项目根目录下新建 static 文件夹
在 static 文件夹中新建 blog 文件
把 css、img、js、vendor 四个素材拷贝到刚刚新建的 blog 文件夹里来
13. 修改 settings.py
打开 settings.py 文件
在最后添加一行
import os
STATICFILES_DIRS = [os.path.join('static'), ]
14. 修改 index.html
15. 此时打开正常
16. 修改 index.html,添加模板参数
找到 index.html 中和博文相关的内容
寻找规律,改成模板写法
找到 index.html 中和博文相关的内容
17.修改 views.py
将 views.py 中的渲染参数按照模板设计的修改
def index(request):
post = {
'link': 'http://www.aiyc.top',
'title': '第一篇博客',
'subtitle': '这是副标题',
'author': 'aiyuechuang',
'date': '2020-09-09'
}
return render(request, 'blog/index.html',
{
"title": "悦创老师的博客",
'post': post,
})
def index(request):
post_list = [
{
'link': 'http://www.aiyc.top',
'title': '第一篇博客',
'subtitle': '这是副标题',
'author': 'aiyuechuang',
'date': '2020-09-09'
},
{
'link': 'http://www.aiyc.top',
'title': '第二篇博客',
'subtitle': '这是副标题',
'author': 'aiyuechuang',
'date': '2020-09-09'
},
]
return render(request, 'blog/index.html',
{
"title": "悦创老师的博客",
"post_list": post_list,
})
18. 博客详情页
把模版的 post.html 拷贝到项目 templates 里面的 blog。
修改 views.py 中的代码
修改前:
def blog_detail(request, blog_id):
return HttpResponse("这是第「{}」篇博客".format(blog_id))
修改后:
def blog_detail(request, blog_id):
return render(request, 'blog/post.html')
这里我的 url 定义是:
urlpatterns = [
path('index/', views.index, name='index'),
# path(route, view, name="'index'")
path('<int:blog_id>', views.blog_detail, name='blog_detail'),
path('<int:blog_id1>/<int:blog_id2>', views.blog_sum, name='blog_sum'),
]
所以,我们测试访问的网页为:
http://localhost:8000/blog/1 # blog 后面跟随数字「我上面的 URL 定义是如此,按你的具体情况而定」
拷贝素材「index 那一步已经导入所需要的素材」,修改所需要的素材的路径,和上面修改 index.html 是一个意思。
可以修改 views.py 中博文的详情页的连接,修改示例如下。
修改前:
def index(request):
post_list = [
{
'link': 'http://www.aiyc.top',
'title': '第一篇博客',
'subtitle': '这是副标题',
'author': 'aiyuechuang',
'date': '2020-09-09'
},
{
'link': 'http://www.aiyc.top',
'title': '第二篇博客',
'subtitle': '这是副标题',
'author': 'aiyuechuang',
'date': '2020-09-09'
},
]
return render(request, 'blog/index.html',
{
"title": "悦创老师的博客",
"post_list": post_list,
})
修改后:
def index(request):
post_list = [
{
'link': '/blog/1',
'title': '第一篇博客',
'subtitle': '这是副标题',
'author': 'aiyuechuang',
'date': '2020-09-09'
},
{
'link': '/blog/2',
'title': '第二篇博客',
'subtitle': '这是副标题',
'author': 'aiyuechuang',
'date': '2020-09-09'
},
]
return render(request, 'blog/index.html',
{
"title": "悦创老师的博客",
"post_list": post_list,
})
就可以实现跳转到我们的详情页。
稍微的进阶,我们可以把详情页的标题换成我们访问的链接。
views.py
def blog_detail(request, blog_id):
return render(request, 'blog/post.html',
{
'title_link': request.path,
'url_host': request.get_host(),
}
)
post.html
<h1>{{url_host}}{{title_link}}</h1>
9. 作业
完善博客系统
完善博客系统的模板和对应的渲染函数
能通过 views.py 中的列表渲染博客首页
4. Django 模型
1. 认识数据库
存储数据的仓库
哪些是数据?
学生的姓名、性别、学号、成绩
用户的银行卡号、余额、交易记录
网站登录账户、密码、报名的课程信息
游戏中的用户名、装备、属性、等级
……
信息时代数据无处不在
2. Django 中的数据库
尝试一下,打开 blog 应用里的 models.py 文件
加入如下内容
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=80)
3. 同步数据库
在命令行运行:
python manage.py makemigrations
得到如下提示,可以看到创建了 Post 模型「也就是生成一个 py 文件,py 文件的内容是如何修改数据库。——生成数据库同步脚本」
继续在命令行运行:
python manage.py migrate
得到如下提示:
4. 利用 admin 后台系统管理数据
将我们创建的模型,注册到后台之中。
修改 blog 文件夹里的 admin.py
from django.contrib import admin
from .models import Post
# Register your models here.
admin.site.register(Post)
在命令行运行 python manage.py runserver
启动服务器
访问:http://localhost:8000/admin/ 登录后可以看到多出来一个新的栏目
5. admin 后台系统管理
点击 Posts 进来可以看到还没有发过内容
点击 ADD POST + 后可直接添加一个 Post 的 Title
保存后内容如下,叫 Post object (1),不直观
6. 修改 models.py
修改 blog 文件夹里的 models.py
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=80)
def __str__(self):
return self.title
刷新页面后可以看到变成以 title 为标题
7. 设计博文模型
一篇博客相关的信息有如下:
- 标题
- 副标题
- 作者
- 发表日期
- 标签
- 分类
- 博文内容
- 博文链接
- (可选)点赞数
- (可选)阅读量
8. Django 中可用的各类模型
- AutoField
- BigAutoField
- BigIntegerField
- BinaryField
- BooleanField
- CharField
- DateField
- DateTimeField
- DecimalField
- DurationField
- EmailField
- FileField
- FileField and FieldFile
- FilePathField
- FloatField
- ImageField
- IntegerField
- GenericIPAddressField
- NullBooleanField
- PositiveIntegerField
- PositiveSmallIntegerField
- SlugField SmallIntegerField
- TextField
- TimeField
- URLField
- UUIDField
9. 设计博文模型——简易版
内容 | 模版 |
---|---|
标题 | CharField |
副标题 | CharField |
作者 | CharField |
发表日期 | DateTimeField |
标签 | CharField |
分类 | CharField |
博文内容 | TextField |
博文链接 | CharField |
(可选)点赞数 | IntegerField |
(可选)阅读量 | IntegerField |
这样设计有什么问题?
10. 设计博文模型——进阶版
11. 博文基础模型
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=80)
subtitle = models.CharField(max_length=80)
published_date = models.DateTimeField()
content = models.TextField()
link = models.CharField(max_length=100)
def __str__(self):
return self.title
12. 关联作者模型
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=80)
subtitle = models.CharField(max_length=80)
published_date = models.DateTimeField()
content = models.TextField()
link = models.CharField(max_length=100)
auth = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
# 利用ForeignKey()即可关联另外一个模型
# on_delete=models.CASCADE:代表如果把这个用户删除的话,就把和用户关联的表也删除
def __str__(self):
return self.title
ForeignKey 外键,一对多的意思,一个作者可以创建多个文章。
所以,作者对文章是一对多的关系,那我们就把作者放在多的这一边。没次检索表,我们都可以通过表来检索作者。
13. 新建分类模型和标签模型
class Category(models.Model):
category_name = models.CharField(max_length=100, blank=True) # blank=True 可以为空
def __str__(self):
return self.category_name
class Tag(models.Model):
tag_name = models.CharField(max_length=100, blank=True)
def __str__(self):
return self.tag_name
14. 关联分类和标签模型
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True) # 就是把这个分类删除,里面的文章也会被删除。
tag = models.ManyToManyField(Tag, blank=True)
利用 ManyToManyField() 也可关联另外一个模型
ForeignKey 和 ManyToManyField 的区别在哪?
15. 一对多
16. 多对多
17. 运行 Django 管理命令
在命令行运行 python manage.py makemigrations
注意:每次修改了 models.py 都需要运行上面这句
18. 完成 makemigrations
19. 运行 Django 管理命令
在命令行运行 python manage.py migrate
注意:makemigrations 完了以后要 migrate
20. 重新运行 Django 服务器
运行 python manage.py runserver
登录 admin 后台查看 Post
21. 向 admin 后台添加模型
修改 blog 文件夹里的 admin.py
from django.contrib import admin
from .models import Post, Category, Tag
# Register your models here.
admin.site.register(Post)
admin.site.register(Category)
admin.site.register(Tag)
22. 添加 Category
在后台添加一个 Python 分类
以后可以直接在新增 Post 时选择 Python 分类
自行添加文章内容、标签等,以供下面操作使用。
23. 从数据库中提取真正的博文信息
from .models import Post
def index(request):
post_list = Post.objects.all().order_by('-published_date')
return render(request, 'blog/index.html',
{
"title": "悦创老师的博客",
"post_list": post_list,
})
24. 设计博客详情页网址
每篇博文有一个英文的网址,如
https://www.aiyc/blog/django-lesson-1
红色部分由数字、字母、短横线、下划线组成
在后台发表时填 Link 只需要填红色部分
25. 修改博客首页的详情页链接
链接设计为/blog/储存的链接
26. 修改 urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
# path(route, view, name="'index'")
# path('<int:blog_id>', views.blog_detail, name='blog_detail'),
path('<slug:blog_link>/', views.blog_detail, name='blog_detail'),
# path('index/<sug:blog_id>', views.blog_detail, name='blog_detail')
path('<int:blog_id1>/<int:blog_id2>', views.blog_sum, name='blog_sum'),
]
slug 表示是由字母、数字以及横杠、下划线组成的字符串
这样就能匹配形如 /blog/django-lesson-1
的网址
并将 django-lesson-1
提取出来存到变量 blog_link
里
27. 修改 views.py
from django.shortcuts import get_object_or_404
def blog_detail(request, blog_link):
post = get_object_or_404(Post, link=blog_link)
return HttpResponse(post.content)
get_object_or_404 表示从某个模型根据关键词提取某段数据
找到就返回数据,找不到就返回404页面
28. 添加博客详情页模板
从博客模板中拷贝 post.html
到 templates/blog/
里
并修改 views.py
def blog_detail(request, blog_link):
post = get_object_or_404(Post, link=blog_link)
return render(request, 'blog/post.html', {'post': post})
29. 修改 post.html 为模板格式
<!-- Page Header -->
<header class="masthead" style="background-image: url('{% static 'blog/img/post-bg.jpg' %}')">
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-heading">
<h1>{{post.title}}</h1>
<h2 class="subheading">{{post.subtitle}}</h2>
<span class="meta">Posted by
<a href="#">{{post.auth}}</a>
on {{post.published_date}}</span>
</div>
</div>
</div>
</div>
</header>
<!-- Post Content -->
<article>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<p>{{post.content}}</p>
<p>Placeholder text by
<a href="https://www.aiyc.top/">AIYC Blog</a>. Photographs by
<a href="https://www.aiyc.top/">aiyuechuang</a>.</p>
</div>
</div>
</div>
</article>
30. 更漂亮的排版
采用 Markdown 格式编写博文
31. 安装 markdown 模块
在命令行运行 pip install markdown2
修改 views.py
32. 页面渲染情况
33. 添加 safe 标签
Django 为了防止被攻击所开启的一个保护,我只需要添加一个 safe 即可。让他信任我所写的内容。
34. 调整 url
现在博客首页网址是 /blog/
,需要调整
my_blog
里的 urls.py
blog 里的 urls.py