课程地址:
慕课网免费视频三小时带你入门Django框架
一、环境搭建
1.1 环境准备
- python环境安装:
使用python版本:3.5+
- 方案1:原生python环境
- 方案2:科学结算Anaconda Python环境(推荐)
减少Python第三方库的困扰,全身心投入到业务开发当中
- IDE工具安装:
- pycharm
说明:该文章基于mac系统,windows和linux类似
1.2 安装andconda
- 到官网下载Andconda
- 添加anaconda环境变量到zsh
1. vim .zshrc
2. add system path
# andconda
export PATH=/opt/anaconda3/bin:$PATH
3. source .zshrc
- 终端输入 conda,显示以下界面说明配置成功
2.3 安装django 2.0
- 命令行安装(使用豆瓣源,下载更快)
pip install -i https://pypi.douban.com/simple/ django==2.0
- 终端输入django-admin,显示以下界面说明安装成功
2.4. pycharm安装
访问官网pycharm进行下载,点击安装即可
二、Django项目初体验
2.1 初识Django项目
2.1.1 Django的基本命令
- startproject 创建一个Django项目
- startapp 创建一个Django应用
- check 检查项目完整性
- runserver 本地简易运行Django项目
- shell 进入Django项目的Python Shell环境
- test 执行Django测试用例
2.1.2 Django的基本指令(数据库相关)
- makemigrations 创建模型变更的迁移文件,生成数据库DDL语句
- migrate 执行上一个命令创建的迁移文件,执行DDL语句
- dumpdata 把数据库数据导出到文件
- loaddata 把文件数据导入到数据库
2.1.3 创建一个项目
- 创建一个项目
cd code/python # 1. 自己创建的python项目目录
django-admin startproject django_introduction # 2. 创建Django项目指令
- 添加代码到gitee仓库
- 使用pycharm打开django_introduction目录
- 配置django_introduction的python环境
2.2 初识Django应用
2.2.1 Django应用 VS Django项目
- 一个Django项目就是一个基于Django的Web应用
- 一个Django应用就是一个可重用的Python软件包
- 每个应用可以自己管理模型、视图、模板、路由和静态文件等
- 一个Djagon项目包含一组配置和若干个Django应用
2.2.2 Django应用目录介绍
- 使用pycharm安装django
问题:conda命令行进入安装的django不在该环境
解决:临时使用pycharm安装
- 创建应用blog,打开terminal,输入 python manage.py startapp blog
- 查看blog目录
2.3. Django HelloWorld
2.3.1 Django视图(What、Why&How)
- 没有框架的时代:hello.html
- 不可能通过HTML表达网页所有的内容
- Django视图产生内容
2.3.2 Django路由(What、What&How)
- runserver 可以看到Django欢迎页面
- 请求没办法到达刚才的视图函数
- 需要配置路由,绑定视图函数和URL
2.3.3 代码编写
- 应用编辑视图blog/views.py
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def hello_world(request):
return HttpResponse("Hello World")
- 应用编辑路由blog/urls.py
from django.urls import path
import blog.views
urlpatterns = [
path("hello_world", blog.views.hello_world)
]
- 项目编辑路由django_introduction/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')) # add this line
]
- 项目安装应用django_introduction/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# myapp blog
'blog.apps.BlogConfig' # add this line
]
- 点击IDE的运行按钮
- 访问http://127.0.0.1:8000/blog/hello_world
- 整个访问流程图如下
三、Django模型层
3.1 模型层简介
3.1.1 模型层是什么
- 位于Django视图层和数据库之间
- Python对象和数据库表之间转换
3.1.2 为什么需要模型层
- 屏蔽不同数据库之间的差异
- 开发者更加专注于业务逻辑的开发
- 提供很多便捷工具有助开发
3.1.3 模型层的相关配置
数据库默认配置在项目settings.py文件,sqlite3数据库
3.2 创建博客文章模型
3.2.1 设计博客模型
- 文章标题 文本类型
- 文章摘要 文本类型
- 文章内容 文本类型
- 唯一ID标记 Int数字类型(自增、主键)
- 发布日期 日期类型
3.2.2 模型层定义字段
- 定义类型
- 数字类型 IntegerField
- 文本类型 TextField
- 日期类型 DateTimeField
- 自增ID AutoField
- 主键定义 primary_key属性
- 应用创建model blog/models.py
class Article(models.Model):
# 文章唯一ID
article_id = models.AutoField(primary_key=True)
# 文章标题(注意TextFiled有括号)
title = models.TextField()
# 文章摘要
brief_content = models.TextField()
# 文章内容
content = models.TextField()
# 文章发布时间
publish_date = models.DateTimeField(auto_now=True)
- 终端运行指令创建Article model
说明:
makemigrations生成ddl(数据库模式定义语言)
migrate真正地去执行ddl
3.3 初识Django Shell
3.3.1 Django Shell是什么
- Python Shell,用于交互式的Python编程
- Django Shell也类似,集成Django项目环境
3.3.2 为什么需要Django Shell
- 临时性操作使用Django Shell更加方便
- 小范围Debug更简单,不需要运行整个项目来测试
方便开发、方便测试、方便Debug
3.3.3 Django Shell的使用
实例:创建一遍文章
3.4. 初识Django Admin模块
4.1 Django Admin模块是什么
- Django的后台管理工具
- 读取定义的模型元数据,提供强大的管理使用页面
4.2 为什么需要Django Admin模块
- Django Shell新增文章太复杂了
- 管理页面是基础设施中重要的部分
- 认证用户、显示管理模型、校验输入等功能类似
4.3 Django Admin模块的使用
- 创建管理员用户
- 登录页面进行管理
- 启动项目,访问网址 http://127.0.0.1:8000/admin
- 输入步骤1创建的管理员账号密码
- 可以发现没有我们自定义的Article -> 应用admin.py注册Article
from django.contrib import admin
# Register your models here.
from .models import Article
admin.site.register(Article)
- 发现Article显示的标题不友好“Article object”,应用models.py 新增str方法,重启服务器
3.5 实现博客数据返回页面
5.1 blog/views.py添加响应
from blog.models import Article
def article_content(request):
article = Article.objects.all()[0]
title = article.title
brief_content = article.brief_content
content = article.content
article_id = article.article_id
publish_date = article.publish_date
return_str = 'title:%s,brief_content:%s,content:%s,article_id:%s,publish_date:%s' % (
title, brief_content, content, article_id, publish_date)
return HttpResponse(return_str)
5.2 blog/urls.py配置路由
urlpatterns = [
path("hello_world", blog.views.hello_world),
path("content", blog.views.article_content) // add this line
]
访问内容地址:http://127.0.0.1:8000/blog/content
四、Django视图与模板
4.1 使用Bootstrap实现静态博客页面
4.1.1 页面布局设计
- 博客首页
- 文章详情页
4.1.2 Bootstrap以及Bootstrap的栅格系统
- 来自美国Twitter的前端框架
- 提供非常多的控件并附带源码
- 栅格系统把页面均分为12等份
- 官方网站:https://www.bootcss.com/
- bootstrap使用:https://v3.bootcss.com/getting-started/
4.1.3 实现静态页面
- 文章标题 blog新建templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三小时入门Django Web框架</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
<h1>三小时入门Django Web框架
<small>-by ybxiang</small></h1>
</div>
<div class="container page-body">
<div class="col-md-9" role="main">
<div class="body-main">
<div>
<h2>文章标题1</h2>
<p>
目标是设定一个定性的时间内目标(通常是一个季度)。关键的结果是由量化指标形式呈现的,用来衡量在这段时间结束时是否达到了目标。 [6]
在全面展开工作时,OKR就存在于公司(顶级愿景)、团队(被继承并由团队生成,而不仅仅是个人目标的一部分)和个人层面(个人发展和个人贡献)上了。
大多数目标通常是由管理层定义的,但有些目标是自下而上的,而不是为了增加团队的积极性。 [7]
公司发布的OKR演示文稿或包含问答的陈述、报告,可以确保在最终完成之前对依赖关系进行跨功能的对齐和协议。
在目标时期结束时,要特别注意对每个目标的每个关键结果进行评估。不同的人对有目标的期望是不同的。谷歌和Uber建议每个季度员工应该实现约70%的“OKR”,这是每个季度的关键业绩数据,而Zynga则希望员工每季度能实现2至3个“OKR”。
[8]
</p>
</div>
</div>
</div>
<div class="col-md-3" role="complementary">
<div>
<h2>最新文章</h2>
<h4><a href="#">最新文章1</a></h4>
<h4><a href="#">最新文章2</a></h4>
<h4><a href="#">最新文章3</a></h4>
<h4><a href="#">最新文章4</a></h4>
<h4><a href="#">最新文章5</a></h4>
<h4><a href="#">最新文章6</a></h4>
<h4><a href="#">最新文章7</a></h4>
<h4><a href="#">最新文章8</a></h4>
<h4><a href="#">最新文章9</a></h4>
</div>
</div>
</div>
</body>
</html>
- 浏览器打开html预览效果
- 文章详情 blog新建templates/detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三小时入门Django Web框架</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
</head>
<body>
<div class="container page-header">
<h1>文章标题1</h1>
</div>
<div class="container body-main">
<p>
目标是设定一个定性的时间内目标(通常是一个季度)。关键的结果是由量化指标形式呈现的,用来衡量在这段时间结束时是否达到了目标。 [6]
在全面展开工作时,OKR就存在于公司(顶级愿景)、团队(被继承并由团队生成,而不仅仅是个人目标的一部分)和个人层面(个人发展和个人贡献)上了。
大多数目标通常是由管理层定义的,但有些目标是自下而上的,而不是为了增加团队的积极性。 [7]
公司发布的OKR演示文稿或包含问答的陈述、报告,可以确保在最终完成之前对依赖关系进行跨功能的对齐和协议。
在目标时期结束时,要特别注意对每个目标的每个关键结果进行评估。不同的人对有目标的期望是不同的。谷歌和Uber建议每个季度员工应该实现约70%的“OKR”,这是每个季度的关键业绩数据,而Zynga则希望员工每季度能实现2至3个“OKR”。
[8]
</p>
</div>
</div>
</body>
</body>
</html>
4.2 初识Django的模板系统
4.2.1 模板系统简介
- 视图文件不适合编码HTML
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
- 页面设计改变需要修改Python代码
- 网页逻辑和网页视图应该分开设计
- 模板系统的表现形式是文本
- 分离文档的表现形式和变现内容
- 模板系统定义了特有的标签占位符
4.2.2 基本语法
- 变量标签:{{ 变量 }}
<html><body>{{ now }}</body></html>
- for循环标签:{% for x in list %}, {% endfor%}
<ul>
{% for item in list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
- if-else分支标签:{% if %},{% else %},{% endif %}
{% if true %}
<p>it is a true part.</p>
{% else %}
<p>it is a false part.</p>
{% endif %}
4.3 使用模板系统渲染博客页面
4.3.1 博客首页
- index.html移动到blog/templates/blog/index.html,读取内容
<div class="container page-body">
<div class="col-md-9" role="main">
<div class="body-main">
{% for article in article_list %}
<div>
<h2>{{ article.title }}</h2>
<p>
{{ article.brief_content }}
</p>
</div>
{% endfor %}
</div>
</div>
<div class="col-md-3" role="complementary">
<div>
<h2>最新文章</h2>
{% for article in article_list %}
<h4><a href="#">{{ article.title }}</a></h4>
{% endfor %}
</div>
</div>
</div>
- views.py放内容
def get_index_page(request):
all_article = Article.objects.all()
return render(request, 'blog/index.html', {
'article_list': all_article
})
- urls.py配置路由
path("index", blog.views.get_index_page)
4.3.2 文章详情页
- detail.html移动到blog/templates/blog/deatail.html,读取内容
<body>
<div class="container page-header">
<h1>{{ curr_article.title }}</h1>
</div>
<div class="container body-main">
<p>
{% for section in section_list %}
<p>{{ section }}</p>
{% endfor %}
</p>
</div>
</body>
- views.py放内容
def get_detail_page(request):
curr_article = Article.objects.all()[0]
section_list = curr_article.content.split('\n')
return render(request, 'blog/detail.html', {
'curr_article': curr_article,
'section_list': section_list
})
- urls.py配置路由
path("detail", blog.views.get_detail_page)
4.4 实现文章详情页面跳转
当前问题:
- 不支持博客首页到文章详情页的跳转
- 只能打开某一遍文章的详情页
当前方案:
- 设计文章详情页URL -> 完善视图函数逻辑 -> 实现首页跳转
4.4.1 设计文章详情页URL
/blog/detail => 不能指定某一篇博客
- /blog/detail/1 => 博客唯一ID为1的文章
- /blog/detail/2 => 博客唯一ID未2的文章
4.4.2 完善视图函数逻辑
URL路径参数的获取和传递
- urls.py 配置路由
path("detail/<int:article_id>", blog.views.get_detail_page)
- views.py 设置数据
def get_detail_page(request, article_id):
all_article = Article.objects.all()
curr_article = None
for article in all_article:
if article.article_id == article_id:
curr_article = article
break
section_list = curr_article.content.split('\n')
return render(request, 'blog/detail.html', {
'curr_article': curr_article,
'section_list': section_list
})
- index.html 修改跳转逻辑
- 访问http://127.0.0.1:8000/blog/index 点击文章标题,跳转到文章详情页
4.5 实现上下篇文章跳转
4.5.1 代码实现
- detail.html新增上下页组件
<body>
<div class="container page-header">
<h1>{{ curr_article.title }}</h1>
</div>
<div class="container body-main">
<p>
{% for section in section_list %}
<p>{{ section }}</p>
{% endfor %}
</p>
</div>
<div>
<nav aria-label="...">
<ul class="pager">
<li><a href="/blog/detail/{{ previous_article.article_id }}">上一篇:{{ previous_article.title }}</a></li>
<li><a href="/blog/detail/{{ next_article.article_id }}">下一篇:{{ next_article.title }}</a></li>
</ul>
</nav>
</div>
</body>
- views.py设置上下页数据
def get_detail_page(request, article_id):
all_article = Article.objects.all()
curr_article = None
previous_article = None
next_article = None
for index, article in enumerate(all_article):
if article.article_id == article_id:
curr_article = article
if index >= 1:
previous_index = index - 1
else:
previous_index = 0
if index < len(all_article) - 1:
next_index = index + 1
else:
next_index = index
previous_article = all_article[previous_index]
next_article = all_article[next_index]
break
section_list = curr_article.content.split('\n')
return render(request, 'blog/detail.html', {
'curr_article': curr_article,
'section_list': section_list,
'previous_article': previous_article,
'next_article': next_article
})
4.6 实现分页功能
4.6.1 实现分页功能流程
- Bootstrap实现分页按钮 -> 设计分页URL -> 使用Django分页组件实现分页功能
4.6.2 index.html 拷贝分页组件
4.6.3实现分页标识设计
- /blog/detail/1 => 博客唯一ID为1的文章
- /blog/index?page = 1 => 分页为1的首页
4.6.4 views.py设置分页数据
- 使用python shell进行分页功能测试
- 登录admin管理后台添加几条article,方便测试分页
- index.html设置UI
- views.py设置数据(倒叙字段签名加【-】)