您的位置:首页 > 编程语言 > Go语言

Django 补充models操作,中间件, 缓存,信号,分页

2016-09-26 20:07 591 查看

1、Model 一对多 补充

models如下:

class UserType(models.Model):
caption = models.CharField(max_length=16)

class UserInfo(models.Model):
username = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
user_type = models.ForeignKey('UserType')


通过queryset查询用户为CEO的用户

>>> from app01.models import UserInfo,UserType
>>> q = UserInfo.objects.filter(user_type__caption='CEO')
>>> print(q)
<QuerySet [<UserInfo: UserInfo object>]>
>>> print(q[0])
UserInfo object
>>> print(q[0].username)
james
>>> print(q[0].pwd)
45569
>>> print(q[0].user_type.caption)
CEO


用values,value_list查询

>>> q = UserInfo.objects.filter(user_type__caption='CEO').values('username','pwd','user_type__caption')
>>> q
<QuerySet [{'pwd': '45569', 'username': 'james', 'user_type__caption': 'CEO'}]>
>>> q[0]
{'pwd': '45569', 'username': 'james', 'user_type__caption': 'CEO'}


value_list 返回元组可以应用到from的select标签

>>> q = UserInfo.objects.filter(user_type__caption='CEO').values_list('username','pwd','user_type__caption')
>>> q
<QuerySet [('james', '45569', 'CEO')]>
>>> q[0]
('james', '45569', 'CEO')


2、model操作 F/Q

F:使用查询条件的值

temp = salary+500
models.UserInfo.objects.filter().update(salary=temp)
update userinfo set salary=salary+500

>>> from django.db.models import F
>>> print(models.UserInfo.objects.values('salary'))
<QuerySet [{'salary': '6500'}, {'salary': '6500'}, {'salary': '6500'}]>
>>> print(models.UserInfo.objects.filter().update(salary=F('salary')+500))
3
>>> print(models.UserInfo.objects.values('salary'))
<QuerySet [{'salary': '7000'}, {'salary': '7000'}, {'salary': '7000'}]>


Q:构造搜索条件
1、传参

>>> models.UserInfo.objects.filter(id=3,user='jasonwang')
<QuerySet [<UserInfo: jasonwang>]>
>>> print(models.UserInfo.objects.filter(id=3,user='jasonwang').query)
SELECT "app01_userinfo"."id", "app01_userinfo"."user", "app01_userinfo"."pwd", "app01_userinfo"."user_type_id", "app01_userinfo"."ctime", "app01_userinfo"."uptime", "app01_userinfo"."img", "app01_userinfo"."email", "app01_userinfo"."address", "app01_userinfo"."salary" FROM "app01_userinfo" WHERE ("app01_userinfo"."id" = 3 AND "app01_userinfo"."user" = jasonwang)


2、传字典

>>> d = {'id':3,'user':'jasonwang'}
>>> models.UserInfo.objects.filter(**d)
<QuerySet [<UserInfo: jasonwang>]>


<input name='id' />
<input name='name' />
获取用户输入,并构造成字典:
models.UserInfo.objects.filter(**d)
3、传Q对象
models.UserInfo.objects.filter(Q对象)

from django.db.models import Q

# q1 = Q()
# q1.connector = 'OR'
# q1.children.append(('id', 1))
# q1.children.append(('id', 2))
# q1.children.append(('id', 3))

# models.Tb1.objects.filter(q1)

>>> q1.connector = 'OR'
>>> q1.children.append(('id',1))
>>> q1.children.append(('id',2))
>>> q1.children.append(('id',3))
>>> qq = models.UserInfo.objects.filter(q1)
>>> print(qq.query)
SELECT "app01_userinfo"."id", "app01_userinfo"."user", "app01_userinfo"."pwd", "app01_userinfo"."user_type_id", "app01_userinfo"."ctime", "app01_userinfo"."uptime", "app01_userinfo"."img", "app01_userinfo"."email", "app01_userinfo"."address", "app01_userinfo"."salary" FROM "app01_userinfo" WHERE ("app01_userinfo"."id" = 1 OR "app01_userinfo"."id" = 2 OR "app01_userinfo"."id" = 3)


# con = Q()
#
# q1 = Q()
# q1.connector = 'OR'
# q1.children.append(('id', 1))
# q1.children.append(('id', 2))
# q1.children.append(('id', 3))
#
# q2 = Q()
# q2.connector = 'OR'
# q2.children.append(('status', '在线'))
#
# con.add(q1, 'AND')
# con.add(q2, 'AND')
#
# models.Tb1.objects.filter(con)

>>> q1.connector = 'OR'
>>> q1.children.append(('id',1))
>>> q1.children.append(('id',2))
>>> q1.children.append(('id',3))
>>> qq = models.UserInfo.objects.filter(q1)
>>> print(qq.query)
SELECT "app01_userinfo"."id", "app01_userinfo"."user", "app01_userinfo"."pwd", "app01_userinfo"."user_type_id", "app01_userinfo"."ctime", "app01_userinfo"."uptime", "app01_userinfo"."img", "app01_userinfo"."email", "app01_userinfo"."address", "app01_userinfo"."salary" FROM "app01_userinfo" WHERE ("app01_userinfo"."id" = 1 OR "app01_userinfo"."id" = 2 OR "app01_userinfo"."id" = 3)
>>> q2 = Q()
>>> q2.connector = 'OR'
>>> q2.children.append(('address','haidian'))
>>> con = Q()
>>> con.add(q1,'AND')
<Q: (OR: ('id', 1), ('id', 2), ('id', 3))>
>>> con.add(q2,'AND')
<Q: (AND: (OR: ('id', 1), ('id', 2), ('id', 3)), ('address', 'haidian'))>
>>> qq = models.UserInfo.objects.filter(con)
>>> print(qq.query)
SELECT "app01_userinfo"."id", "app01_userinfo"."user", "app01_userinfo"."pwd", "app01_userinfo"."user_type_id", "app01_userinfo"."ctime", "app01_userinfo"."uptime", "app01_userinfo"."img", "app01_userinfo"."email", "app01_userinfo"."address", "app01_userinfo"."salary" FROM "app01_userinfo" WHERE (("app01_userinfo"."id" = 1 OR "app01_userinfo"."id" = 2 OR "app01_userinfo"."id" = 3) AND "app01_userinfo"."address" = haidian)
>>> print(qq)
<QuerySet [<UserInfo: jason>]>
>>> print(qq[0])
jason
>>>


3、model多对多操作

- 创建

a. 方式一:
class B2G(models.Model):
b_id = models.ForeignKey('Boy')
g_id = models.ForeignKey('Girl')

class Boy(models.Model):

username = models.CharField(max_length=16)

class Girl(models.Model):

name = models.CharField(max_length=16)

b. 方式二:
class Boy(models.Model):

username = models.CharField(max_length=16)
# girl_set
class Girl(models.Model):

name = models.CharField(max_length=16)

b = models.ManyToManyField('Boy')

- 操作:
添加:
正向

g1 = models.Girl.objects.get(id=1)

g1.b.add(models.Boy.objects.get(id=1))
g1.b.add(1)

bs = models.Boy.objects.all()
g1.b.add(*bs)
g1.b.add(*[1,2,3])


反向

b1 = models.Boy.objects.get(id=1)
b1.girl_set.add(1)
b1.girl_set.add(models.Girl.objects.all())

b1.girl_set.add(*[1,2,3,4])


...
删除:

g1 = models.Girl.objects.get(id=1)
g1.b.clear() # 清空和girl ID=1所关联的所有数据

g1.b.remove(2)
g1.b.remove(*[1,2])


查询:

g1 = models.Girl.objects.get(id=1) # SQL
g1.b.all()    # SQL
g1.b.filter().count()

b1 = models.Boy.objects.get(id=1)
b1.girl_set.all()

models.Girl.objects.all().values('id','name', 'b__username')
models.Boy.objects.all().values('id','username', 'girl__name')


更新:

ORM:
python操作数据库模块:
MySQLdb
pymysql

原生SQL
# from django.db import connection
# cursor = connection.cursor()
# cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
# row = cursor.fetchone()

4、中间件

中间件介绍:

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。
每个中间件都会负责一个功能,例如,AuthenticationMiddleware,与sessions处理相关。

激活中间件:

需要在settings.py配置文件中,配置MIDDLEWARE_CLASSES:

MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# 'django.middleware.cache.FetchFromCacheMiddleware',
]


当然你也可以不试用任何的中间件,这个可以设置为空。

中间件顺序

一般我们我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下,process request 和 process response的执行顺序正好相反,当有请求过来的时候,默认从上倒下执行!然后在返回的时候从下面在返回回去,如下图所示。

#!/usr/bin/env python
# _*_coding:utf-8_*_
from django.utils.safestring import mark_safe

class PageInfo(object):
def __init__(self,current,totalItem,peritems=5):
self.__current=current
self.__peritems=peritems
self.__totalItem=totalItem
def From(self):
return (self.__current-1)*self.__peritems
def To(self):
return self.__current*self.__peritems
def TotalPage(self):  #总页数
result=divmod(self.__totalItem,self.__peritems)
if result[1]==0:
return result[0]
else:
return result[0]+1

def Custompager(baseurl,currentPage,totalpage):  #基础页,当前页,总页数
perPager=11
#总页数<11
#0 -- totalpage
#总页数>11
#当前页大于5 currentPage-5 -- currentPage+5
#currentPage+5是否超过总页数,超过总页数,end就是总页数
#当前页小于5 0 -- 11
begin=0
end=0
if totalpage <= 11:
begin=0
end=totalpage
else:
if currentPage>5:
begin=currentPage-5
end=currentPage+5
if end > totalpage:
end=totalpage
else:
begin=0
end=11
pager_list=[]
if currentPage<=1:
first="<a href=''>首页</a>"
else:
first="<a href='%s%d'>首页</a>" % (baseurl,1)
pager_list.append(first)

if currentPage<=1:
prev="<a href=''>上一页</a>"
else:
prev="<a href='%s%d'>上一页</a>" % (baseurl,currentPage-1)
pager_list.append(prev)

for i in range(begin+1,end+1):
if i == currentPage:
temp="<a href='%s%d' class='selected'>%d</a>" % (baseurl,i,i)
else:
temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
pager_list.append(temp)
if currentPage>=totalpage:
next="<a href='#'>下一页</a>"
else:
next="<a href='%s%d'>下一页</a>" % (baseurl,currentPage+1)
pager_list.append(next)
if currentPage>=totalpage:
last="<a href=''>末页</a>"
else:
last="<a href='%s%d'>末页</a>" % (baseurl,totalpage)
pager_list.append(last)
result=''.join(pager_list)
return mark_safe(result)   #把字符串转成html语言


分页实例
总结,分页时需要做三件事:

创建处理分页数据的类

根据分页数据获取数据

输出分页HTML,即:[上一页][1][2][3][4][5][下一页]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: