python web框架Django入门
背景及介绍
-
Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的框架模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。
-
Django 项目是一个python定制框架,它源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来。Django 框架的核心组件有:
-
用于创建模型的对象关系映射
-
为最终用户设计的完美管理界面
-
一流的 URL 设计
-
设计者友好的模板语言
-
缓存系统。
-
-
Django 是用python语言写的开源web开发框架(open source web framework),它鼓励快速开发,并遵循MVC设计。Django遵守BSD版权,初次发布于2005年7月, 并于2008年9月发布了第一个正式版本1.0 。
-
Django 根据比利时的爵士音乐家Django Reinhardt命名,他是一个吉普赛人,主要以演奏吉它为主,还演奏过小提琴等。
-
由于Django在近年来的迅速发展,应用越来越广泛,被著名IT开发杂志SD Times评选为2013 SD Times 100,位列“API、库和框架”分类第6位,被认为是该领域的佼佼者[1] 。
Web 框架简单,易学易上手,但是自己要着手处理很多问题。 框架复杂,学习周期稍长,但是很多问题框架已经处理或屏蔽。
同类框架---> tornado flask
2005年面世, 目前比较成熟的版本:1.10.1,支持python2.7、3.4、3.5
Django 架构设计
Django是一个基于MVC构造的框架。不过在Django中、控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式。
MVC
-
大部分开发语言中都用到MVC框架
-
MVC框架的核心思想是:解耦
-
降低各功能模块值间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用
-
M:表示Model,只要用于对数据库层的封装
-
V:表示View,用于向用户展示结果
-
C:表示Controller,是核心,用于处理请求,获取数据,返回结果
MVT
-
M:Model 模型 负责业务对象和数据对象,处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。(即与数据库进行相关交互操作)
-
T:Template 模板 存取模型及调取恰当模板的相关逻辑。模型与模板的桥梁。即(页面展示)
-
V:View 视图 处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。(业务逻辑的实现)
Django 工作机制
-
用manage .py runserver 启动Django服务器时就载入了在同一目录下的settings .py。该文件包含了项目中的配置信息,如前面讲的URLConf等,其中最重要的配置就是ROOT_URLCONF,它告诉Django哪个Python模块应该用作本站的URLConf,默认的是urls.py
-
当访问url的时候,Django会根据ROOT_URLCONF的设置来装载URLConf。
-
然后按顺序逐个匹配URLConf里的URLpatterns。如果找到则会调用相关联的视图函数,并把HttpRequest对象作为第一个参数(通常是request)
-
最后该view函数负责返回一个HttpResponse对象。
Django特点
-
强大的数据库支持:用python的类继承,几行代码就可以拥有一个丰富,动态的数据库操作接口(API),如果需要你也能执行SQL语句
-
灵活的URL转发:使用正则表达式匹配URL,你可以设计任意的URL,没有框架的特定限定,灵活高效。
-
强大的模板系统:使用Django强大而可扩展的模板语言,可以分隔设计、内容和Python代码。并且具有可继承性。
-
便捷的表单处理:你可以方便的生成各种表单模型,实现表单的有效性检验。可以方便的从你定义的模型实例生成相应的表单。
-
缓存系统:与memcached或其它的缓存系统联用,更出色的表现,更快的加载速度。
-
会话系统:内置session存储技术用户登录与权限检查,快速开发用户会话功能。
-
国际化:内置国际化系统,方便开发出多种语言的网站。
学习资料
-
Django官方网站:https://www.djangoproject.com/
-
Django documentation:https://www.djangoproject.com/en/dev/
-
The Django Book:http://djangobook.py3k.cn/
-
Django 基础教程:https://code.ziqiangxuetang.com/django/django-tutorial/html
-
Django 学习交流论坛:http://www.pythonzh.cn/
-
Django入门学习规划与资料推荐:http://zmrenwu.com/post/15/
1.入门
-
1.1 环境搭建
-
1.2 定义模型
-
1.3 使用后台管理
-
1.4 编写视图
-
1.5 定义模板
1.1搭建开发环境
Windows创建虚拟环境
-
pip install virtualenv 或者 pip install virtualenvwrapper-win
-
安装完成后创建虚拟环境:virtualenv 虚拟环境名 或者 mkvirtualenv 虚拟环境名称
-
进入到Script中执行activate启动虚拟环境 或者 workon 虚拟环境名称
-
进入到Script中执行deactivate关闭虚拟环境 或者 deactivate
-
查看当前环境的扩展包:pip list
-
pip install django==1.11
-
详细说明:https://blog.csdn.net/submarineas/article/details/84551883
-
验证是否安装成功,在python交互式命令下:
import django
django.VERSION
(1, 10, 1, u'final', 0)
django.get_version()
'1.11'
Django 项目搭建
命令行方式
创建项目
-
django-admin startproject demo(项目名称)
-
会在当前目录下生成一个文件夹,包含manage.py 和一个名为demo的文件夹
-
一个Django项目至少要包含1个以上的应用app
-
python web项目中只有设置的静态文件夹才可以直接被外部访问
-
新建APP
-
切换到新生成的项目文件夹下
-
python manage.py startapp appname(项目名称)
-
生成的目录结构
-
主文件夹
-
Demo1 项目文件夹
-
settings.py :整个Django项目的配置文件
-
urls.py:整个Django项目的路由(所有的请求都是通过整个文件找到对应的页面)
-
wsgi.py:项目部署的时候使用的框架
-
-
appname 应用文件夹
-
templates 模板文件夹(可能需要手动添加)
-
static 静态文件夹(可能需要手动添加)
-
__init__.py app初始化文件,说明该文件夹是一个python包
-
admin.py app 管理文件,添加后台管理时会用
-
apps.py app配置文件
-
models.py 数据库模板文件。
-
tests.py 测试文件
-
view.py 视图文件,主要的后台业务处理
-
-
manage.py 项目管理文件
-
-
-
修改Settings.py中的INSTALLED_APPS,在最后添加上刚刚的APP的名字,如果是pycharm创建的项目不需要手动添加。
修改显示中文、中国时区
-
使用pycharm打开项目注意选择虚拟环境
-
在项目的settings.py文件中找到
LANGUAGE_CODE = 'en-us'
改成LANGUAGE_CODE = 'zh-hans'
-
在项目的settings.py文件中找到TIME_ZONE = 'UTC' 改成TIME_ZONE = ‘Asia/Shanghai’
命令行启动Djange项目
-
python manage.py runserver [127.0.0.1:8080] 最后一个参数可选,指定IP和端口号
-
启动成功后在浏览器中输入127.0.0.1:8080看到 it works或者它正常工作了,则项目搭建成功
数据库配置
-
在setttings.py中的DATABASES字典中添加配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'inner_manage',
'USER':'root',
'PASSWORD':'toor',
'HOST':'127.0.0.1',
'PORT':'3306'
}
}
需要安装mysqlclient(虚拟环境下安装):pip install mysqlclient
如果安装不成功,需要进行源码安装:去官网下载类似于mysqlclient-1.4.4-cp37-cp37m-win32.whl这样的源码文件。
安装也是在虚拟环境下安装,进入虚拟环境,转到源码文件的目录下安装,pip install mysqlclient-1.4.4-cp37-cp37m-win32.whl
pycharm方式
pycharm创建的项目有诸多限制,建议使用命令行创建项目和app。采用pycharm进行编辑和开发。
pycharm安装
-
双击pycharm安装包运行安装
-
pycharm采用java开发,所以安装运行时需要jre的执行环境。
-
安装完成后提示需要激活pycharm,选择
License server
,输入http://idea.imsxm.com/
,active即可激活。
创建项目
-
选择File-->New Project-->选择Django,选择python版本和项目路径
-
在more settings中输入application name可以在创建项目是包含一个app。
-
如果不生成初始的app,则需要手动执行命令行添加app。
-
生成后的项目目录结构和利用命令行创建的项目路径一致。其余的操作就都和上面一样。
项目配置
-
通过修改Run-->Edit Configurations中的Port修改访问项目的端口号,默认是8000有可能被占用。
项目运行
-
pycharm的右上角有一个绿色的小箭头,点击后下方出现控制台,并且输出以下内容,则说明项目启动成功。
System check identified no issues (0 silenced).
You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
November 06, 2018 - 14:01:10
Django version 1.10.1, using settings 'SQLT.settings'
Starting development server at http://127.0.0.1:8081/
Quit the server with CTRL-BREAK.
Django项目的访问流程
-
访问流程:客户浏览器的请求先到达url.spy中,在urlpatterns列表中寻找相应的路径(通过正则表达式进行匹配),通过路径找到views中对应的函数或方法,然后将请求提交给views中进行处理,views通过从models获取到数据,并通过数据将templates中的页面渲染,并响应给客户端。
-
Django整站技术架构
1.2定义模型
设计介绍
-
本示例完成“商品分类-商品”信息的维护,需要存储两种数据:分类、商品
-
分类表结构设计:
-
表名:TypeInfo
-
类型名称:tname
-
类型添加时间:tadd_date
-
-
商品表结构设计:
-
表名:GoodsInfo
-
商品名称:gname
-
商品价格:gprice
-
商品简介:gdetail
-
所属分类:gtype
-
-
分类-商品的关系为一对多
数据库配置
-
在settings.py文件中,通过DATABASES项进行数据库设置
-
django支持的数据库包括:sqlite、mysql等主流数据库
-
Django默认使用SQLite数据库
创建应用
-
在一个项目中可以创建一到多个应用,每个应用进行一种业务处理
-
创建应用的命令:
python manage.py startapp goods
定义模型类
-
有一个数据表,就有一个模型类与之对应
-
打开models.py文件,定义模型类
-
引入包from django.db import models
-
模型类继承自models.Model类
-
说明:不需要定义主键列,在生成时会自动添加,并且值为自动增长
-
当输出对象时,会调用对象的str方法
from django.db import models
class TypeInfo(models.Model):
tname = models.CharField(max_length=20,verbose_name='分类名称')
tadd_date = models.DateTimeField()
def _ _str_ _(self):
return "%d" % self.pk
class GoodsInfo(models.Model):
gname...
gprice...
gdetail...
isDelete...
gtype = models.ForeignKey(TypeInfo,on_delete=models.CASCADE)# 级联删除
def __str__(self):
return self.gname
生成数据表
-
激活模型:编辑settings.py文件,将goods应用加入到installed_apps中
-
生成迁移文件:根据模型类生成sql语句
python manage.py makemigrations
-
迁移文件被生成到应用的migrations目录
-
执行迁移:执行sql语句生成数据表
python manage.py migrate
测试数据操作
-
进入python shell,进行简单的模型API练习
python manage.py shell
-
引入需要的包:
from booktest.models import BookInfo,HeroInfo from django.utils import timezone from datetime import *
-
查询所有分类信息:
TypeInfo.objects.all()
-
新建分类信息:
t = TypeInfo() t.tname="图书" t.badd_date=datetime(year=1990,month=1,day=10) t.save()
-
查找分类信息:
t=TypeInfo.objects.get(pk=1)
-
输出分类信息:
t t.id t.tname
-
修改分类信息:
t.tname="零食" t.save()
-
删除图书信息:
t.delete()
关联对象的操作
-
对于HeroInfo可以按照上面的操作方式进行
-
添加,注意添加关联对象
g=GoodsInfo() g.gname='开心果' g.hprice=100 g.gdetail='开开心心' g.gtype=t g.save()
-
获得关联集合:返回当前type对象的所有goods
t.goodsinfo_set.all()
-
有一个TypeInfo存在,必须要有一个GoodsInfo对象,提供了创建关联的数据:
g=t.goodsinfo_set.create(gname='碧根果',gprice=100,gdetail='好吃不上火')
1.3使用后台管理
管理操作
-
站点分为“内容发布”和“公共访问”两部分
-
“内容发布”的部分负责添加、修改、删除内容,开发这些重复的功能是一件单调乏味、缺乏创造力的工作。为此,Django会根据定义的模型类完全自动地生成管理模块
使用django的管理
-
创建一个管理员用户
python manage.py createsuperuser,按提示输入用户名、邮箱、密码
-
启动服务器,通过“127.0.0.1:8000/admin”访问,输入上面创建的用户名、密码完成登录
-
进入管理站点,默认可以对groups、users进行管理
管理界面本地化
-
编辑settings.py文件,设置编码、时区
LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai'
向admin注册goods相关的模型
-
打开goods/admin.py文件,注册模型
from django.contrib import admin from models import TypeInfo,GoodsInfo # 注册方式如下: admin.site.register(TypeInfo) admin.site.register(GoodsInfo)
-
刷新管理页面,可以对TypeInfo的数据进行增删改查操作
-
问题:如果在str方法中返回中文,在修改和添加时会报ascii的错误
-
解决:在str()方法中,将字符串末尾添加“.encode('utf-8')”
自定义管理页面
-
Django提供了admin.ModelAdmin类
-
通过定义ModelAdmin的子类,来定义模型在Admin界面的显示方式
class GoodsInfoAdmin(admin.ModelAdmin): ... # 注册方式如下: admin.site.register(GoodsInfo,GoodsInfoAdmin)
列表页属性
-
list_display:显示字段,可以点击列头进行排序
list_display = ['pk', 'gname', 'gprice']
-
list_filter:过滤字段,过滤框会出现在右侧
list_filter = ['gname']
-
search_fields:搜索字段,搜索框会出现在上侧
search_fields = ['gname']
-
list_per_page:分页,分页框会出现在下侧
list_per_page = 10
添加、修改页属性
-
fields:属性的先后顺序
fields = ['gname', 'gprice']
-
fieldsets:属性分组
fieldsets = [ ('basic',{'fields': ['gname']}), ('more', {'fields': ['gprice']}), ]
关联对象
-
对于GoodsInfo模型类,有两种注册方式
-
方式一:与TypeInfo模型类相同
-
方式二:关联注册
-
-
按照TypeInfo的注册方式完成GoodsInfo的注册
-
接下来实现关联注册
from django.contrib import admin from models import TypeInfo,GoodsInfo class GoodsInfoInline(admin.StackedInline): model = GoodsInfo extra = 2 class TypeInfoAdmin(admin.ModelAdmin): inlines = [GoodsInfoInline] admin.site.register(TypeInfo, TypeInfoAdmin)
-
可以将内嵌的方式改为表格
class GoodsInfoInline(admin.TabularInline)
布尔值的显示
-
发布性别的显示不是一个直观的结果,可以使用方法进行封装
models.py模型类中定义 def gender(self): if self.hgender: return '男' else: return '女' gender.short_description = '性别'
-
在admin注册中使用gender代替hgender
class HeroInfoAdmin(admin.ModelAdmin): list_display = ['id', 'hname', 'gender', 'hcontent']
1.4视图
-
在django中,视图对WEB请求进行回应
-
视图接收reqeust对象作为第一个参数,包含了请求的信息
-
视图就是一个Python函数,被定义在views.py中
from django.http import HttpResponse def index(request): return HttpResponse("index") def detail(request,id): return HttpResponse("detail %s" % id)
-
定义完成视图后,需要配置urlconf,否则无法处理请求
URLconf
-
在Django中,定义URLconf包括正则表达式、视图两部分
-
Django使用正则表达式匹配请求的URL,一旦匹配成功,则调用应用的视图
-
注意:只匹配路径部分,即除去域名、参数后的字符串
-
在test1/urls.py插入goods,使主urlconf连接到goods.urls模块
url(r'^', include('goods.urls')),
-
在goods中的urls.py中添加urlconf
from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.index), url(r'^([0-9]+)/$', views.detail), ]
1.5模板
-
模板是html页面,可以根据视图中传递的数据填充值
-
修改settings.py文件,设置TEMPLATES的DIRS值
'DIRS': [os.path.join(BASE_DIR, 'templates')],
-
在模板中访问视图传递的数据
{{输出值,可以是变量,也可以是对象.属性}} {%执行代码段%}
定义index.html模板
<!DOCTYPE html> <html> <head> <title>首页</title> </head> <body> <h1>图书列表</h1> <ul> {%for good in goodslist%} <li> <a href="{{good.id}}"> {{good.gname}} </a> </li> {%endfor%} </ul> </body> </html>
定义detail.html模板
-
在模板中访问对象成员时,都以属性的方式访问,即方法也不能加括号
使用模板
-
编辑views.py文件,在方法中调用模板
from django.http import HttpResponse from django.template import RequestContext, loader from models import GoodsInfo def index(request): goodslist = GoodsInfo.objects.all() template = loader.get_template('index.html') context = RequestContext(request, {'goodslist': goodslist}) return HttpResponse(template.render(context)) def detail(reqeust, id): good = GoodsInfo.objects.get(pk=id) template = loader.get_template('detail.html') context = RequestContext(reqeust, {'good': good}) return HttpResponse(template.render(context))
去除模板的硬编码
-
在index.html模板中,超链接是硬编码的,此时的请求地址为“127.0.0.1/1/”
<a href="{{good.id}}">
-
看如下情况:将urlconf中详细页改为如下,链接就找不到了
url(r'^good/([0-9]+)/$', views.detail),
-
此时的请求地址应该为“127.0.0.1/good/1/”
-
问题总结:如果在模板中地址硬编码,将来urlconf修改后,地址将失效
-
解决:使用命名的url设置超链接
-
修改test1/urls.py文件,在include中设置namespace
url(r'^admin/', include(admin.site.urls, namespace='booktest')),
-
修改good/urls.py文件,设置name
url(r'^book/([0-9]+)/$', views.detail, name="detail"),
-
修改index.html模板中的链接
<a href="{%url 'good:detail' book.id%}">
Render简写
-
Django提供了函数Render()简化视图调用模板、构造上下文
from django.shortcuts import render from models import GoodsInfo def index(reqeust): goodslist = GoodsInfo.objects.all() return render(reqeust, 'index.html', {'goodslist': goodslist}) def detail(reqeust, id): good = GoodsInfo.objects.get(pk=id) return render(reqeust, 'detail.html', {'good': good})
添加静态文件
-
在app的文件夹下创建一个名为static的文件夹,将css js image等文件放在static目录下。
-
settings.py STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), )
-
在html文件头部添加
{% load static %}
,在html文件中链接资源文件的地方,改写成{% static 'css/style.css' %}
。即可实现动态访问,修改方便
总结:项目搭建过程:命令行
1.创建项目工程:django-admin startproject 项目名称
2.创建应用(模块):进入到manage.py所在目录:python manage.py startapp 应用名称goods
3.settings.py:INSTALLED_APPA ->goods
4.编写模型
5.python manage.py makemigrations(生成迁移文件)
6.同步数据库完成迁移:python manage.py migrate
7.创建超级用户:python manage.py createsuperuser 用户名 邮箱 密码 再次输入密码