0%

Django_note

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
![](https://s25.postimg.org/rt9qz91m7/RUL.png)

*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重定向:**
![](https://s25.postimg.org/4vmz9r7fz/redirect.jpg)
_ _ _

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

欢迎关注我的其它发布渠道