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百度205000-8000103华为20> 10000101.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_text1.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_id3、将模型注册到后台管理界面 注册管理后台 • 投票的问题和选项,可以通过后台进行录入、编辑 • 只要把模型注册到后台管理界面即可
# 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、视图、模板和表单使用》