Django入门
MVC:模块–>视图–>控制器
模块只要和数据库进行交互,比如模型类的数据表,应用名_模块名.sql
views视图就是显示界面用的,模板语言开发
客户端.发出请求–>控制器.控制器接收请求给视图或者模块,视图封装了一些html、css、js,内嵌模板引擎,模块和数据库交互,内嵌ORM框架,它们返回给控制器结果,然后给浏览器接收渲染
Django开源Web开发框架,是MVT
模块–>视图–>模板
模块和关系型数据库交互,如果和非关系型数据库交互,就引入第三方模块调用
模块中有ORM,可以将模块对象转化为关系型数据库中的表,把数据库中的数据转换为python中的对象
使用sqlite数据库交互
安装虚拟环境
安装pip
apt-get install python-pip
安装virtualenv
pip install virtualenv
安装python-virtualenv
apt-get install python-virtualenv
安装virtualenvwrapper
pip install virtualenvwrapper
创建目录存放虚拟环境
mkdir $HOME/.virtualenvs
在用户环境变量~/.bashrc中添加行:
1 2
| export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh
|
应用环境变量
source ~/.bashrc
创建python虚拟环境
mkvirtualenv py_django
进入虚拟环境
workon py_django
退出虚拟环境
deactivate
找一份配置好的虚拟环境里面的django,进入虚拟环境
pip freeze>list.txt
之后进另一个环境,安装
pip install -r list.txt
解压tar包
tar -xvf xxx.tar
1. 创建项目
django-admin startproject 项目名
2. 创建应用
python manage.py startapp 应用名
3. 安装应用,在项目的settings.py里面安装应用
1 2 3 4
| INSTALLED_APPS = ( ... ... '应用名', )
|
4. 测试服务器
python manage.py runserver ip:8000或者python manage.py runserver
设计模型
在应用里面的models里面定义模型,继承自models.Model类,叫模型类
使用django进行数据库开发:
(1)在models.py中定义模型类
(2)生成数据文件,迁移数据
(3)通过类和对象完成数据crud(增删改查缩写)
首先定义模型类:
在应用里面的models里面定义模型
5. 之后生成数据文件
python manage.py makemigrations
6. 迁移数据
python manage.py migrate
7. 在shell中进行数据库操作
python manage.py shell
后台管理:
(1)管理界面本地化
(2)创建超级管理员
(3)注册模型类
(4)自定义管理页面
8. 本地化显示,修改项目里面的setting.py文件
1 2
| LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai'
|
9. 创建超级管理员:
python manage.py createsuperuser
进入管理界面
127.0.0.1:8000/admin
10. 登录管理界面后,并没有图书,英雄的管理入口,所以要注册模型类,实现crud操作,修改应用里面的admin.py文件注册:
1 2 3 4 5 6 7 8 9 10 11 12 13
| from django.contrib import admin from models import * # 导入./models.py中的BookInfo和HeroInfo class BookInfoAdmin(admin.ModelAdmin): # 继承自admin.ModelAdmin类 list_display = ['id', 'title', 'pub_date'] # list_display显示要显示的属性 class HeroInfoAdmin(admin.ModelAdmin): list_display = ['id', 'name', 'content', 'gender', 'book'] admin.site.register(BookInfo, BookInfoAdmin) # 注册书类 admin.site.register(HeroInfo, HeroInfoAdmin) # 注册英雄类
|
视图:
(1)定义视图
·视图就是一个python函数,被定义在views.py文件中
·视图的第一个参数是HttpRes对象ponse对象,包含返回给请求者的响应信息
(2)配置URLconf
11. 定义视图:
1 2 3 4 5 6
| from django.shortcuts import render from django.http import HttpResponse def index(request): return HttpResponse('hello world')
|
配置URLconf
·查找视图的过程:请求者在浏览器地址中输入url,请求到网站后,获取url信息,然后与编写好的URLconf逐条匹配,如果匹配成功返回对应的视图,如果都没有匹配,返回404错误
·一条URlconf中包括url规则和视图两部分
url规则可以使用正则
视图就是在views.py中定义的视图
·配置URLconf
在应用中先定义URLconf
包含到项目的URLconf中
12. 配置应用的URLconf,创建应用里面的urls.py文件:
1 2 3 4 5 6
| from django.conf.urls import url import views urlpatterns = [ url(r'^$', views.index), ]
|
13. 包含到项目的urls.py文件中,为urlpatterns列表增加项:
1 2 3 4
| urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^', include('booktest.urls')), # 增加包含应用里面的urls ]
|
在浏览器地址中访问127.0.0.1:8000/,返回hello world
模板:
·给请求者返回一个漂亮的页面,在Django中,把前端的内容定义在模板中,然后再把模板提交给视图调用,然后效果就出来了
14. 创建模板,在应用的同级目录下创建template文件夹,再在里面创建和应用同名的文件夹,之后创建一个index.html
15. 修改模板的路径,修改项目里面的setting.py文件,设置TEMPLATES的DIRS值:
1 2 3 4 5 6
| TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.hoin(BASE_DIR, 'templates')], 'APP_DIRS': True, ... ...
|
16. 定义模板,修改templates/booktest/index.html文件:
1 2 3 4
| <h1>{{title}}</h1> {%for i in list%} {{i}}<br> {%endfor%}
|
17. 视图调用模板,先找到模板,之后定义上下文,再渲染模板,因为都要执行这三个操作,于是django提供了一个render函数封装代码,render方法包含三个参数,第一个参数是request对象,第二个参数是模板文件路径,第三个参数是字典,表示向模板中传递上下文的数据,修改应用里面的views.py文件:
1 2 3 4 5 6 7
| #coding:utf-8 from django.shortcuts import render def index(request): context={'title':'图书列表','list':range(10)} return render(request,'booktest/index.html',context)
|
18. 完成项目,定义视图,修改应用里面的views.py文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| from django.shortcuts import render from models import BookInfo # 首页,展示所有图书 def index(reqeust): # 查询所有图书 booklist = BookInfo.objects.all() # 将图书列表传递到模板中,然后渲染模板 context = {'booklist':booklist} return render(request, 'booktest/index.html', context) # 详细页,接收图书的编号,根据编号查询,再通过关系找到本图书的所有英雄并展示 def detail(reqeust, id): # 根据图书编号对应图书 hero = BookInfo.objects.get(pk=id) context = {'book': hero} # 将图书信息传递到模板中,然后渲染模板 return render(reqeust, 'booktest/detail.html', context)
|
19. 定义URLconf,修改应用里面的urls.py文件:
1 2 3 4 5 6 7 8 9
| from django.conf.urls import url # 引入视图模块 import views urlpatterns = [ # 配置首页url url(r'^$', views.index), # 配置详细页url,\d+表示多个数字,小括号用于取值,建议复习下正则表达式 url(r'^(\d+)$',views.detail), ]
|
20. 修改templates/应用名/index.html文件:
1 2 3 4 5 6 7 8 9 10
| <h1>图书列表</h1> <ul> {# 遍历图书列表#} {%for book in booklist%} <li> {# 输出图书名称,并设置超链接,链接地址是一个数字#} <a href="{{book.id}}">{{book.title}}</a> </li> {%endfor%} </ul>
|
21. 创建templates/应用名/detail.html文件:
1 2 3 4 5 6 7 8
| <h1>{{book.btitle}}</h1> <ul> {# 通过关系找到本图书的所有英雄,并遍历#} {%for hero in book.heroinfo_set.all%} {# 输出英雄的姓名及描述#} <li>{{hero.name}}---{{hero.content}}</li> {%endfor%} </ul>
|
重点
查询filter(), get(), exclude()
比较运算符
逻辑运算符Q | ~
模糊查询:contains, startswith, endswith
范围查询:in=[]
空判断:isnull
两个属性的判断:F
ORM:对象-关系型数据库映射
低耦合,高内聚
**MVC框架中的Model模块中包括ORM

# 关系字段类型:
ForeignKeyKe:一对多,把字段定义在多的一端中
使用mysql交互
1. 创建项目,创建应用
2. 之后修改项目里面的setting.py文件,把应用写入INSTALLED_APPS,修改DATABASES,改为mysql交互,添加交互:
1 2 3 4 5 6 7 8 9 10
| DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 修改为mysql 'NAME':'azhen', # 数据库名 'HOST':'localhost', 'PORT':3306, 'USER':'root', 'PASSWORD':'mysql', } }
|
生成迁移文件,就是根据类生成sql脚本,迁移就是创建数据库表的过程
3. 创建数据库
1 2
| mysql -uroot -pmysql # 使用用户名root,密码mysql,进入mysql数据库 create database azhen charset=utf8; # 创建azhen数据库,并设置类型utf8
|
元选项:应用名称_模型类名称,数据表默认名字
如果不指定表的名称为xxx,那么当表生成后,表的名字是:应用名称_模型类名称
4. 创建模型类,再创建元类,指定数据库表名,之后生成迁移文件,再迁移文件,然后在数据库的指定表名中,添加数据(read和comment是mysql关键字)
属性object:默认的django管理器,是Manager类型的对象,用于和数据库交互
管理器
django支持自定义管理器类,继承自models.Manager,它可以更改原始的查询集,可以向管理器的类中添加额外的方法
5. 自己添加一个自定义管理器,在应用里面的models.py文件添加:
1 2 3 4 5 6 7 8 9 10
| class BookInfoManager(models.Manager): # 原始查询集的更改 def get_queryset(self): return super(BookInfoManager, self).get_queryset().filter(isDelete=False) 模型类 books = BookInfoManager()
|
7. 在自定义管理器中新增一个模型类方法
1 2 3 4 5 6 7 8 9
| # 新增模型类的方法 def create(self, title, pub_date): book = BookInfo() book.title = title book.pub_date = pub_date book.bread = 0 book.bcomment = 0 book.isDelete = False return book
|
8. 展示图书信息,配置url,配置添加项目的urls
1 2 3 4
| urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url('^', include('booktest.urls')), ]
|
9. 在应用里面创建一个urls.py文件:
1 2 3 4 5 6 7
| #coding:utf-8 from django.conf.urls import url import views urlpatterns = [ url('^$', views.index), ]
|
10. 在应用里面的views.py里面配置index
1 2 3 4 5
| from django.shortcuts import render def index(request): return render(request, 'booktest/index.html')
|
11. 在应用的同级目录下创建模板templates/应用名/index.html
12. 在应用的views.py里面查询数据,并返回给index.html:
1 2 3 4 5 6 7 8
| from django.shortcuts import render from models import BookIndo def index(request): list = BookInfo.books.all() context = {'booklist':list} return render(request, 'booktest/index.html', context)
|
13. index视图显示:
1 2 3 4 5
| <ul> {%for book in booklist%} <li>{{book.title}}</li> {%endfor%} </ul>
|
14. 提示模板不存在,在项目的setting.py中修改:
1 2 3 4 5
| TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join('templates')], # 模板路径 ... ...
|
逻辑删除数据表数据:
update bookinfo set isDelete=0 where id=1;
15. 在index视图中添加删除和增加操作:
1 2 3 4 5 6 7
| <a href="/add/">增加</a> <hr> <ul> {%for book in booklist%} <li>{{book.title}}---<a href="/{{book.id}}/">删除</a></li> {%endfor%} </ul>
|
16. 在应用的urls.py里面增加新的url:
1 2 3 4 5
| urlpatterns = [ url('^$', views.index), url('^add/$', views.add), url('^(\d+)/$', views.delete), ]
|
17. 在应用里面的view.py定义一个增加一个删除函数,并导入重定向参数redirect:
1 2 3 4 5 6 7 8 9 10 11 12 13
| from django.shortcuts import render, redirect ... ... def add(request): book = BookInfo.books.create('流星蝴蝶剑', date(2017,1,1)) book.save() return redirect('/') def delete(request,id): book = BookInfo.books.get(id=id) book.isDelete = True book.save() return redirect('/') # 转向到首页
|
查询集
两大特性,一是:惰性查询并不会访问数据库获取数据,当index视图调用数据时,才会去数据库调用数据;二是:查询集的结果被保存,再次查询时会使用之前缓存的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| # 显示前两个id书名 list = BookInfo.books.all()[0:2] # 全部查询 list = BookInfo.books.all() # 查询id=1的书 # list = BookInfo.books.filter(id=1) # 查询书名包含‘龙’的书 # list = BookInfo.books.filter(btitle__contains='龙') # 查询书名以‘剑’结尾的书 # list = BookInfo.books.filter(btitle__endswith='剑') # 查询id是1,3,5的书 # list = BookInfo.books.filter(pk__in=[1,3,5]) # 查询id大于3的书 # list = BookInfo.books.filter(id__gt=3) # 查询id不包括3的书 # list = BookInfo.books.exclude(id=3) # 查询1980年的书 # list = BookInfo.books.filter(bpub_date__year=1980) # 查询1980.1.1之后发表的书 # list = BookInfo.books.filter(bpub_date__gt=date(1980,1,1)) # 一对多,显示书名里面的英雄,用index2显示 # list = HeroInfo.objects.filter(hbook__btitle='天龙八部') # context = {'herolist':list} # return render(request, 'booktest/index2.html', context) # list = BookInfo.books.filter(bread__gt=F('bcommet')) # list = BookInfo.books.filter(bread__gt=F('bcommet')*2) # list = BookInfo.books.filter(heroinfo__hcontent__contains='八') # 逻辑与,惰性查询,xxx.filter(bread__gt=20, id__lt=3)之后,并不会访问数据库获取数据,当index视图调用数据时,才会去数据库调用数据,所以执行顺序是where bread > 20 and id < 3,而不是 先获取bread>20 --> 后获取id<3 # list = BookInfo.books.filter(bread__gt=20, id__lt=3) # list =BookInfo.books.filter(Q(bread__gt=20) | Q(id__lt=3)) # list = BookInfo.books.filter(~Q(id=3)) # 聚合函数aggregate,导包Sum # result = BookInfo.books.aggregate(Sum('bread')) # result = BookInfo.books.count() # print result
|
View
URLconf视图被调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| HttpRequest:GET、POST、COOKIES、Session HttpResponse:render() (1)JsonResponse (2)HttpResponseRedirect:redirect() (3)set_cookie(键,值) ``` ## 视图 **视图就是一个python函数,接收HttpRequest对象,返回HttpResponse** **URL和视图的匹配规则** URL匹配过程: http://127.0.0.1:8000/booktest/index/ 先匹配根项目下的urls,之后匹配到^booktest规则,之后通过包含的booktest.urls匹配到应用里面的urls,再匹配,之后匹配到^index/,再之后就会调用views里面的index  *r'^':防止转译字符\ r'\d' == '\\d'* **获取参数**
|
urlpatterns = [
url(‘^$’, views.index),
url(r’^(?P\d+)/$’, views.show),
]
def show(request, book_id):
return HttpResponse(‘show %s’%book_id)
1 2 3 4 5
| **403错误,屏蔽cs|rf认证** _ _ _ ## HttpRequest对象
|
属性:
path
method
COOKIES
Session
GET、POST
1 2
| **get请求方式的参数:a=10&b=30**
|
/1/?a=10&b=30
request.GET
1 2 3 4 5 6 7 8 9 10
| **什么时候用GET:超链接请求的参数 --> ?键=值&键=值&键=值** **什么时候用get,什么时候用getlist** **表单控件提交规则:以name为键,以value为值,构成键值提交 (1)单选按钮、多选按钮:被选中的提交 (2)如果没有name属性,就不提交** _ _ _ ## HttpResponse对象
|
render()
set_cookie()
JSONResponse
HttpResponseRedirect–redirect()
```
Redirect重定向:

状态保持
状态保持就是相当于网站记录了你的操作,如逛淘宝的最近浏览,两种方式:客户端使用Cookie,服务器端使用Session