Django简介
• Django是一个开放源代码的Web应用框架,由Python写成
框架介绍
• Django 框架的核心组件有:
– 用于创建模型的对象关系映射
– 为最终用户设计的完美管理界面
– 一流的 URL 设计
– 设计者友好的模板语言
– 缓存系统
MTV模式
• Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同
– M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)
– T 代表模板 (Template):负责如何把页面展示给用户(html)
– V 代表视图(View):负责业务逻辑,并在适当时候调用Model和Template
• 除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template
MTV响应模式
• Web服务器(中间件)收到一个http请求
• Django在URLconf里查找对应的视图(View)函数来处理http请求
• 视图函数调用相应的数据模型来存取数据、调用相应的模板向用户展示页面
• 视图函数处理结束后返回一个http的响应给Web服务器
• Web服务器将响应发送给客户端
虚拟环境
虚拟环境可以理解为就是一个目录,克隆python到这个目录,安装模块到虚拟环境,将来不用的时候,可以直接把虚拟环境的目录删除。
安装django
[root@room9pc01 exercise]# mkdir day17
[root@room9pc01 exercise]# cd day17
[root@room9pc01 day17]# ls
[root@room9pc01 day17]# python3 -m venv /opt/djenv/ //创建python虚拟环境目录
[root@room9pc01 day17]# ls /opt/djenv/
bin include lib lib64 pyvenv.cfg
[root@room9pc01 day17]# source /opt/djenv/bin/activate //激活python虚拟环境
(djenv) [root@room9pc01 day17]# cd /root/桌面/python/zzg_pypkgs/dj_pkgs
(djenv) [root@room9pc01 dj_pkgs]# ls
asn1crypto-0.24.0-py2.py3-none-any.whl
cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl
cryptography-2.3.1-cp34-abi3-manylinux1_x86_64.whl
Django-1.11.6-py2.py3-none-any.whl
idna-2.7-py2.py3-none-any.whl
pycparser-2.18.tar.gz
PyMySQL-0.9.2-py2.py3-none-any.whl
pytz-2018.5-py2.py3-none-any.whl
six-1.11.0-py2.py3-none-any.whl
(djenv) [root@room9pc01 dj_pkgs]# pip install * //安装django
###########################################################################
(djenv) [root@room9pc01 dj_pkgs]# pip install django==1.11.6 //在线安装django
创建项目
• Djanog可以自动生成一些代码,这些代码创建一个Django项目:一个Django实例的设置集合,包括数据库的配置、Django有关的选项和应用有关的选项
(djenv) [root@room9pc01 dj_pkgs]# cd -
(djenv) [root@room9pc01 day17]# ls
(djenv) [root@room9pc01 day17]# django-admin startproject mysite //创建项目mysite
(djenv) [root@room9pc01 day17]# ls
mysite
(djenv) [root@room9pc01 day17]# tree mysite/
mysite/ # 项目的根目录
├── manage.py # 项目管理工具
└── mysite # 项目配置目录
├── __init__.py
├── settings.py # 配置文件
├── urls.py # 程序的入口文件 URLConf
└── wsgi.py # 将项目部署到Web服务器时应用
项目文件说明
• 外层的mysite/根目录仅仅是项目的一个容器。 它的名字与Django无关;可以将其重命名为你喜欢的任何内容
• manage.py:一个命令行工具,可以使用多种方式对Django项目进行交互。 可以在django-admin和manage.py中读到关于manage.py的所有细节
• 内层的mysite/目录是项目的真正的Python包。 它是导入任何东西时将需要使用的Python包的名字(例如 mysite.urls)
• mysite/init.py:一个空文件,它告诉Python这个目录应该被看做一个Python包
• mysite/settings.py:该Django 项目的设置/配置。Django settings 将告诉你这些设置如何工作。
• mysite/urls.py:此Django项目的URL声明;Django驱动网站的“目录”
• mysite/wsgi.py:用于项目的与WSGI兼容的Web服务器入口
开发服务器
• Django自带一个开发服务器,默认运行于8000端口
• 该开发服务器不要应用在生产环境下
测试站点
(djenv) [root@room9pc01 day17]# cd mysite/
(djenv) [root@room9pc01 mysite]# python manage.py runserver //django提供了一个测试服务器,功能简单,不能用于生产环境
浏览器访问http://127.0.0.1:8000/
配置pycharm
(1)File -> Settings -> Project: day03 -> Project Interpreter -> 点右上角齿轮 -> add Local -> Existing environment (勾选Make available to all project) -> 点右侧… -> /opt/djenv/bin/python
(2)File -> Settings -> Languages & Frameworks -> django -> Enable django support -> django project root 填写外层mysite目录 -> settings 选择mysite/settings.py
配置项目数据库
(djenv) [root@room9pc01 mysite]# mysql -uroot -p123456
MariaDB [(none)]> CREATE DATABASE dj1812 DEFAULT CHARSET UTF8;
修改django设置
# mysite/settings.py(#开头表示配置该文件,下同)
28 ALLOWED_HOSTS = '*' //允许所有主机访问
77 DATABASES = { //数据库访问设置
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dj1812',
'USER': ' root'
'PASSWORD': '123456'
'HOST': '127.0.0.1'
'PORT': '3306'
}
}
111 LANGUAGE_CODE = 'zh-hans' //中文
113 TIME_ZONE = 'Asia/Shanghai' //上海时区
119 USE_TZ = False
############################################################################
# mysite/__init__.py
import pymysql
pymysql.install_as_MySQLdb()
############################################################################
(djenv) [root@room9pc01 mysite]# ls
db.sqlite3 manage.py mysite
(djenv) [root@room9pc01 mysite]# systemctl stop httpd
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80
生成数据库
• Django生成的项目,使用了很多预先编写好的应用,这些应用需要用到数据
• 只要执行以下语句,即可自动生成数据库生成内建应用的表
(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
(djenv) [root@room9pc01 mysite]# python manage.py migrate
(djenv) [root@room9pc01 mysite]# mysql -uroot -p123456
MariaDB [(none)]> use dj1812
MariaDB [dj1812]> show tables; #查看上一步生成的表
创建管理员账户
• 访问后台需要有超级用户身份
• 超级用户需要单独创建
• 用户将写到数据库中
(djenv) [root@room9pc01 mysite]# python manage.py createsuperuser
依次输入:管理员用户名(默认root),邮箱地址,密码(必须大于8个字符,且不能全为数字)
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80
浏览器访问后台管理页面 :http://127.0.0.1/admin
创建应用
- 软件开发也希望能实现即插即用一样的功能,在编写python程序时,本着DRY(Don’t Repeat Yourself)原则。
- 可以把一个项目拆解成很多应用。每一个应用编写好后,还可以集成到其他项目。
应用简介
• 应用是一个Web应用程序,它完成具体的事项 ——比如一个博客系统、一个存储公共档案的数据库或者一个简单的投票应用
• 项目是特定网站的配置和应用程序的集合
• 一个项目可以包含多个应用
• 一个应用可以运用到多个项目中去
创建应用
• 应用可以放在Python path上的任何位置
• 可以在manage.py文件同级目录创建应用,以便可以将它作为顶层模块导入,而不是mysite的子模块
案例:创建网页投票结果统计项目
(djenv) [root@room9pc01 mysite]# python manage.py startapp polls //创建应用polls
集成应用到项目
# mysite/settings.py
33 INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls', #激活应用polls
]
配置URLconf
• 为了整洁起见,用户与polls相关的url都交给polls应用进行路由
url规划
- http://127.0.0.1/polls/:投票首页,列出全部的问题
- http://127.0.0.1/polls/1/:1号问题投票详情
- http://127.0.0.1/polls/1/result/:1号问题的投票结果
授权
- 项目的入口是mysite/urls.py,如果所有应用涉及到的网址全部写到这个文件,文件内容将会非常多,不便于管理。
- 为了方便管理,将某一应用的URL交给应用处理。比如投票应用的url都以polls/开头,所以将以polls/开头的URL交给polls应用处理。
# mysite/urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^polls/', include('polls.urls')),
]
一、创建首页
1、配置urll
# mysite/polls/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
# url(正则, 函数, name=该url的名字),
url(r'^$', views.index, name='index'), //正则匹配首页(http://127.0.0.1/polls/,后续所有网页的url配置均从http://127.0.0.1/polls/之后的字符开始匹配)
]
创建视图
• 视图是URLconf路由到某一URL时执行的函数
• 为上一步polls主页编写简单视图,编辑polls/views.py如下:
2、编写函数
# mysite/polls/views.py
from django.shortcuts import render
def index(request): //首页函数
return render(request, 'index.html')
函数至少需要有一个参数,用户的请求会传给该参数。返回值是通过render函数调用一个模板,将模板文件发送给用户。
3、创建模板文件index.html
(djenv) [root@room9pc01 polls]# mkdir templates //模板文件目录名必须为templates
(djenv) [root@room9pc01 polls]# ls
admin.py __init__.py models.py templates urls.py
#############################################################################
# mysite/polls/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>投票首页</title>
</head>
<body>
<div class="container">
<h1>投票首页</h1>
</div>
</body>
</html>
4、测试
(djenv) [root@room9pc01 polls]# cd ..
(djenv) [root@room9pc01 mysite]# ls
db.sqlite3 manage.py mysite polls
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80
浏览器访问http://127.0.0.1/出现404是正常的,因为确实没有定义;访问http://127.0.0.1/polls/才能显示应用的首页。
二、创建投票详情页
1、配置url
# mysite/polls/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
#url(正则,函数,name=该url的名字)
url(r'^$', views.index, name='index'), //正则匹配首页(http://127.0.0.1/polls/)
url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'), 正则匹配投票详情页(http://127.0.0.1/polls/num/,注num表示任意整数)
]
2、编写函数
# mysite/polls/views.py
from django.shortcuts import render
# Create your views here.
def index(request): //首页函数
return render(request, 'index.html')
def detail(request, question_id): //投票详情页函数
return render(request, 'detail.html', {'qid': question_id})
3、创建模板文件index.html
# mysite/polls/templates/detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>投票详情</title>
</head>
<body class="container">
<h1>{{ qid }}号投票详情</h1> //{{ qid }}变量接收投票详情页函数传递过来的question_id的值
</body>
</html>
4、测试访问
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80
浏览器访问http://127.0.0.1/polls/1/
三、创建投票结果页
1、配置url
from django.conf.urls import url
from . import views
urlpatterns = [
#url(正则,函数,name=该url的名字)
url(r'^$', views.index, name='index'), //正则匹配首页(http://127.0.0.1/polls/)
url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'), //正则匹配投票详情页(http://127.0.0.1/polls/num/)
url(r'^(?P<question_id>\d+)/result/$', views.result, name='result'), //正则匹配投票结果页(http://127.0.0.1/polls/num/result/)
]
2、编写函数
# mysite/polls/views.py
from django.shortcuts import render
# Create your views here.
def index(request): //首页函数
return render(request, 'index.html')
def detail(request, question_id): //投票详情页函数
return render(request, 'detail.html', {'qid': question_id})
def result(request, question_id): //投票结果页函数
return render(request, 'result.html', {'qid': question_id})
四、django模型
模型理念
• 模型指出了数据的唯一、明确的真实来源
• 它包含了正在存储的数据的基本字段和行为
• Django遵循DRY(Do not Repeat Yourself) 原则
• 这个原则的目标是在一个地方定义你的数据模型,并自动从它获得需要的信息
模型说明
• 每个模型都用一个类表示,该类继承自django.db.models.Model
• 每个模型都有一些类变量,在模型中每个类变量都代表了数据库中的一个字段
• 每个字段通过Field类的一个实例表示 —— 例如字符字段CharField和日期字段DateTimeField。 这种方法告诉Django,每个字段中保存着什么类型的数据
• 每个Field 实例的名字就是字段的名字,并且是机器可读的格式
• 在Python代码中将使用到它的值,并且数据库将把它用作表的列名
本项目polls应用模型构思
- 模型对应数据库。投票应用需要的字段有:问题ID、问题内容、选项、票数。
- 经过分析,需要两张表:问题表,选项表
• 在这个简单的投票应用中,我们将创建两个模型:Question和Choice
• Question对象具有一个question_text(问题)属性和一个publish_date(发布时间)属性
• Choice有两个字段:选择的内容和选择的得票统计
• 每个Choice与一个Question关联
(1)问题表:
ID | 内容 |
---|---|
1 | 期待的工资? |
2 | 希望进入的公司? |
(2)选项表:
ID | 内容 | 问题ID | 票数 |
---|---|---|---|
1 | 百度 | 2 | 0 |
5000-8000 | 1 | 0 | |
3 | 华为 | 2 | 0 |
> 10000 | 1 | 0 |
1.1、编写问题模型
# mysite/polls/models.py
from django.db import models
class Question(models.Model): //定义问题模型的类
question_text = models.CharField(max_length=200, unique=True, null=False)
pub_date = models.DateTimeField()
def __str__(self):
return '问题: %s' % self.question_text
1.2、生成问题表
迁移Django储存模型
• polls应用建立了新的模型,该模型需要反馈到数据库中
• 通过运行makemigrations告诉Django,已经对模型做了一些更改,并且会将这些更改记录为迁移文件
• 迁移文件位于polls/migrations/目录下
生成数据库
• makemigrations只是生成了迁移文件,并未真正的反馈到数据中
• migrate才是真正生成数据库
(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
(djenv) [root@room9pc01 mysite]# python manage.py migrate
MariaDB [(none)]> use dj1812
MariaDB [dj1812]> show tables;
#会发现多了一个表:polls_question,命名规则为polls_类名(小写)
MariaDB [dj1812]> desc polls_question;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| question_text | varchar(200) | NO | UNI | NULL | |
| pub_date | datetime | NO | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
2.1、编写选项模型
#mysite/polls/models.py
from django.db import models
# Create your models here.
class Question(models.Model): //定义问题模型的类
question_text = models.CharField(max_length=200, unique=True, null=False)
pub_date =models.DateTimeField()
def __str__(self):
return '问题: %s' % self.question_text
class Choice(models.Model): //定义选项模型的类
choice_text = models.CharField(max_length=200, null=False)
votes = models.IntegerField(default=0)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
def __str__(self):
return '%s => %s' % (self.question, self.choice_text)
2.2、生成选项表
(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
(djenv) [root@room9pc01 mysite]# python manage.py migrate
(djenv) [root@room9pc01 mysite]# mysql -uroot -p123456```
MariaDB [(none)]> use dj1812
MariaDB [dj1812]> show tables;
会发现多了一个表:polls_choice
MariaDB [dj1812]> desc polls_choice;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| choice_text | varchar(200) | NO | | NULL | |
| votes | int(11) | NO | | NULL | |
| q_id | int(11) | NO | MUL | NULL | |
+-------------+--------------+------+-----+---------+----------------+
因为Question和Choice是有主外键约束的,也就是说一个问题可以对应多个选项。但是一个选项只能对应一个问题。在Choice中,q是外键,数据库自动为它加上_id,成为外键字段,如果Choice中用的是question,那么外键字段的名字就是question_id。
将Choice类中的q改为question。完成之后更新数据库:
(djenv) [root@room9pc01 mysite]# python manage.py makemigrations
Did you rename choice.q to choice.question (a ForeignKey)? [y/N] y
(djenv) [root@room9pc01 mysite]# python manage.py migrate
MariaDB [dj1812]> desc polls_choice;
MariaDB [dj1812]> desc polls_choice;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| choice_text | varchar(200) | NO | | NULL | |
| votes | int(11) | NO | | NULL | |
| question_id | int(11) | NO | MUL | NULL | |
+-------------+--------------+------+-----+---------+----------------+
发现q_id变成了question_id
3、将模型注册到后台管理界面
注册管理后台
• 投票的问题和选项,可以通过后台进行录入、编辑
• 只要把模型注册到后台管理界面即可
# mysite/polls/admin.py
from django.contrib import admin
from .models import Question, Choice
# Register your models here.
admin.site.register(Question)
admin.site.register(Choice)
4、启动开发服务器
(djenv) [root@room9pc01 mysite]# python manage.py runserver 0:80
浏览器访问后台http://127.0.0.1/admin/,添加一些问题和选项,如下图所示:
接下一篇博客《python:django API、视图、模板和表单使用》