一 准备工作
1 python 环境安装
官网下载安装python
即可.
科学计算 Anaconda2 Python环境
减少Python第三方库的困扰,全身心的投入到业务开发当中
官网: https://www.anaconda.com/
快速下载: https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
PS: 安装完之后,在环境变量中,会自动加入 anaconda
的环境变量.但我们在使用的时候, 之前还需要 source ~/.bash_profile
之后就可以正常使用命令 conda
了.
PS: 只有最新版支持自己的MAC系统. 版本为 Anaconda3-2020.11-MacOSX-x86_64.pkg
, MAC版本为 10.15.7
2 创建虚拟环境
source ~/.bash_profile
创建一个虚拟环境 mkvirtualenv -p /usr/local/bin/python3 djangoenv (mkvirtualenv djangoenv) 上面设置了默认为 python3,但是测试的时候不行。 djangoenv
是自己取的虚拟环境的名称.
1. 列出虚拟环境:lsvirtualenv -b
2. 切换虚拟环境:workon env1
3. 退出虚拟环境:deactivate
4. 删除虚拟环境:rmvirtualenv test2
进入我们刚刚建立的虚拟环境 workon djangoenv
文档: https://blog.csdn.net/codipy/article/details/104709535
2-9 虚拟环境 virtualenv的安装
3 django环境安装
-
django版本:2.0, 进入项目目录之后,运行
pip3 install django==2.2
, 之后运行djaongo-admin
查看是否安装成功. 出现如下信息,表示安装成功. -
安装如果慢的话, 使用
pip3 install django==2.2 -i https://pypi.douban.com/simple
加上 豆瓣源,速度会快. -
使用python包依赖工具 pip3 安装
4 pycharm ide安装并进入项目把项目的虚拟环境设置为 上面设置的环境.
- PyCharm->Preferences…->Project:django_introduction->Project Interpreter->选择刚刚建立的虚拟环境
PS: 我本地的环境是在 ~/.env/djangoenv/bin/python3.7
其中 djangoenv
是上面我自己取的虚拟环境的名称.
二 Django项目初体验
1 初始Django项目
① Django 的基本命令
django-admin
startproject
创建一个django
项目startapp
创建一个django
应用check
校验项目的完整性runserver
进入django
环境并且运行django
项目, 本地简易运行django
项目shell
进入django
项目的python shell
环境test
执行django
用例测试
Django的基本命令(数据库相关)
makemigrations
创建模型变更的迁移文件migrate
执行上一个命令创建的迁移文件dumpdata
把数据库数据导出到文件loaddata
把文件数据导入到数据库
② 创建一个项目
django-admin startproject django_introduction
django_introduction
是自己取得项目名称.
③ 项目目录介绍
django_introduction/settings.py
配置文件
django_introduction/urls.py
路由文件
django_wsgi.py
python作为wsgl
应用所需要的一些文件的内容.
manage.py
项目管理文件
④ 运行项目
python3 manage.py runserver
之后用 http://127.0.0.1:8000/
就可以访问了. 如下就可以用了.
2 初始Django应用
① django 应用 VS django 项目
- 一个 django 项目就是一个基于django的web应用
- 一个 django 应用就是一个可重用的 python 软件包
- 每个应用可以自己管理模型,视图,模板,路由和静态文件等
一个django项目包含一组配置和若干个django应用
② django 应用目录介绍
python3 manage.py startapp blog
创建一个名字叫blog
的应用. 会出现如下新的目录
文件名 | 用途 |
---|---|
views.py | 视图处理的地方 |
models.py | 定义应用模型的地方 |
admin.py | 定义admin模块管理对象的地方 |
apps.py | 声明应用的地方 |
test.py | 编写应用测试用例的地方 |
urls.py | (自行创建)管理应用路由的地方 |
3 Django HelloWorld
① django 视图(what,why,how)
- 没有框架的时代: hello.html
- 不可能通过HTML表达网页所有的内容
- django视图产生内容
举例
- 在
blog/views.py
中加入如下代码
from django.shortcuts import render
from django.http import HttpRequest
# Create your views here.
def hello_world(request):
return HttpRequest("hello world")
② django 路由(what,why,how)
- runserver 可以看到 django 欢迎页面
- 请求没办法到达刚才的视图函数
- 需要配置路由绑定视图函数和URL
举例
- 配置
blog
应用路由, 在blog
下新建urls.py
并加入如下代码
from django.urls import path,include
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'))
]
- 把应用加到配置文件
django_introduction
下面的settings.py
中.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# self new create app
'blog.apps.BlogConfig'
]
- 重新运行项目
python3 manage.py runserver
- 在浏览器中打开
http://127.0.0.1:8000/blog/hello_world
就可以看到hello world
字样.
三 初识django模型层
1 模型层简介
① 模型层是什么
- 位于 django 视图层和数据库之间
- python对象和数据库表之间转换
② 为什么需要模型层
- 屏蔽不同数据库之间的差异
- 开发者更加专注于业务逻辑的开发
- 提供很多便捷工具有助开发
③ 模型层的相关配置
在项目下面的 settings.py
中, 有关数据库的配置
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
2 创建博客文章模型
① 设计博客模型
- 文章标题 文本类型
- 文章摘要 文本类型
- 文章内容 文本类型
- 唯一ID标记 int数字类型(自增,主键)
- 发布日期 日期类型
② 模型层定义字段
- 数字类型: IntegerFiled
- 文本类型: TextField
- 日期类型: DateTimeField
- 自增id: AutoFiled
- 主键定义: primary_key 属性
- 在
blog/models.py
中,定义模型
from django.db import models
# Create your models here.
class Article(models.Model):
# 文章的唯一id
article_id = models.AutoField(primary_key=True)
# 文章标题
title = models.TextField()
# 文章的摘要
brief_content = models.TextField()
# 文章的主要内容
content = models.TextField()
# 文章的发布日期
publish_date = models.DateTimeField(auto_now=True)
- 在命令行中,运行命令,把模型写到数据库中
python3 manage.py makemigrations
此时,在blog/migrations
文件夹中会出现,模型文件
运行上面的迁移文件
python3 manage.py migrate
3 初识 django shell
① django shell 是什么
- python shell, 用于交互式的 python 编程
- django shell也类似, 继承 django 项目环境
② 为什么需要django shell
- 临时性操作使用 django shell 更加方便
- 小范围 debug 更简单,不需要运行整个项目来测试
- 总结:
方便开发,方便调试,方便debug
③ django shell的使用
- 命令后进入
django shell
命令:python3 manage.py shell
举例: 用 django shell
新建一篇文章.
from blog.models import Article
a = Article()
a.title = 'Test django shell'
a.brief_content = 'Test django shell, by zqs teacher'
a.content = 'Test django shell, new article,main content'
a.save() # 保存到数据库
# 查询所有文章
articles = Article.objects.all()
article = articles[0]
print(article.title) # 输出: Test django shell
4 初识 django admin模块
① django admin 模块是什么
- django的后台管理工具
- 读取定义的模型元数据, 提供强大的管理使用页面
② 为什么需要 django admin 模块
- django shell 新增文章太复杂了
- 管理页面是基础设置中重要的部分
- 认证用户,显示管理模型,校验输入等功能类似
③ django admin 模块的使用
- 创建管理员用户
python3 manage.py createsuperuser
, 依次填入账号,密码. 邮箱可不填. - 登录页面进行管理
http://127.0.0.1:8000/admin/
- 把之前写的
blog
模型在blog/admin.py
中注册一下.
from django.contrib import admin
# Register your models here.
from .models import Article
admin.site.register(Article)
5 实现博客数据返回页面
- 在
blog\views.py
下加入article_content
函数
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
from blog.models import Article
def hello_world(request):
return HttpResponse("hello world")
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)
- 配置应用级别路由
blog/urls.py
中加入 如下:
from django.urls import path,include
import blog.views
urlpatterns = [
path('hello_world', blog.views.hello_world),
path('content', blog.views.article_content),
]
- 配置全局级别路由
django_introduction/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]
已经配置过 blog 了.所以不需要再配置了.
四 初始django视图与模板
1 使用 boostrap 实现静态博客页面
- 页面布局设计
- 博客首页
- 文章详情页
- boostrap 以及 bootstrap的栅格系统
- 来自美国Twitter的前端框架
- 提供非常多的控件并附带源码
- 栅格系统把页面均分为十二等份
- 实现静态页面
- 在
blog
下新建一个目录templates
, 并在下面建立一个index.html
和detail.html
2 初始django的模板系统
① 模板系统简介
- 视图文件不适合编码HTML
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
- 页面设计改变时候需要修改python代码,非常的不方便
- 网页逻辑和网页视图应该分开设计
- 模板系统的表示形式是文本
- 分离文档的表现形式和表现内容
- 模板系统定义了特有的标签占位符
② 基本语法
- 变量标签:
{{变量}}
<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 %}
3 使用模板系统渲染博客页面
① 博客首页
<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>
在 blog/views.py
中新增
def get_index_page(request):
all_article = Article.objects.all()
# 渲染
return render(request, 'blog/index.html', {
'article_list': all_article
})
配置应用路由 blog/urls.py
urlpatterns = [
path('hello_world', blog.views.hello_world),
path('content', blog.views.article_content),
path('index', blog.views.get_index_page)
]
② 文章详情页
在 blog/views.py
中新增
def get_detail_page(request):
curr_article = Article.objects.all()[0]
return render(request, 'blog/detail.html', {
'curr_article': curr_article
})
配置应用路由 blog/urls.py
urlpatterns = [
path('hello_world', blog.views.hello_world),
path('content', blog.views.article_content),
path('index', blog.views.get_index_page),
path('detail', blog.views.get_detail_page)
]
4 实现文章详情页的跳转
① 设计文章详情页url
/blog/detail/1
=> 博客唯一ID为1的文章/blog/detail/2
=> 博客唯一ID为2的文章/blog/detail/3
=> 博客唯一ID为3的文章
② 完善视图函数逻辑
- URL路径参数的获取和传递
blog/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
return render(request, 'blog/detail.html', {
'curr_article': curr_article
})
blog/urls.py
中修改如下
urlpatterns = [
path('hello_world', blog.views.hello_world),
path('content', blog.views.article_content),
path('index', blog.views.get_index_page),
# path('detail', blog.views.get_detail_page)
path('detail/<int:article_id>', blog.views.get_detail_page)
]
③ 实现首页跳转
<h2><a href="/blog/detail/{{ article.article_id }}">{{ article.title }}</a></h2>
5 实现上下篇文章跳转
- 修改
blog/detail.html
文件如下
<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>
- 修改
blog/views.py
如下
def get_detail_page(request, article_id):
all_article = Article.objects.all()
curr_article = None
previous_index = 0
next_index = 0
previous_article = None
next_article = None
for index, article in enumerate(all_article):
if index == 0:
previous_index = 0
next_index = index + 1
elif index == len(all_article) - 1:
previous_index = index - 1
next_index = index
else:
previous_index = index - 1
next_index = index + 1
if article.article_id == article_id:
curr_article = article
previous_article = all_article[previous_index]
next_article = all_article[next_index]
break
return render(request, 'blog/detail.html', {
'curr_article': curr_article,
'previous_article': previous_article,
'next_article': next_article
})
6 实现最近文章列表
① boostrap 实现分页按钮
<div class="body-footer">
<div class="col-md-4 col-md-offset-3">
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
② 设计分页 url
/blog/index/1
=> 分页为1的首页/blog/index?page=1
=> 分页为1的首页
/blog/views.py
中修改如下
def get_index_page(request):
page = request.GET.get('page')
all_article = Article.objects.all()
if page:
page = int(page)
else:
page = 1
print(page)
return render(request, 'blog/index.html', {
'article_list': all_article
})
③ 使用 django 分页组件实现分页功能
- 略过