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