Day20 Django之Model多对多、中间件、缓存、信号和分页

时间:2023-03-09 15:49:46
Day20 Django之Model多对多、中间件、缓存、信号和分页

一、Form补充

class IndexForm(forms.Form):
# c = [
# (1, 'CEO'),
# (2, 'CTO')
# ]
# 静态字段,属于IndexForm类,即使数据库增加页面不会显示
c = models.UserType.objects.all().values_list('id','caption')
user_type_id = forms.IntegerField(widget=forms.Select(choices=c))
# 需要加上构造方法
def __init__(self, *args, **kwargs):
#父类构造方法:1.获取所有的静态字段 2.fields = []
super(IndexForm, self).__init__(*args, **kwargs)
#print(self.fields['user_type_id'].widget.choices)
self.fields['user_type_id'].widget.choices = models.UserType.objects.all().values_list('id','caption') def index(request):
form = IndexForm()
return render(request, 'index.html', {'form':form})

views.py

二、数据操作之F/Q

创建数据:

def index(request):
for i in range(10):
models.UserType.objects.create(caption='CE'+str(i))
c = models.UserType.objects.all().count()
print(c)

导入F/Q:

from django.db.models import F,Q

单表操作:

q1 = Q()
q1.connector = 'OR'
q1.children.append(('id', 1))
q1.children.append(('id', 2))
q1.children.append(('id', 3)) obj = models.UserType.objects.filter(q1)
for item in obj:
print(item.id, item.caption)

连表操作:

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(('caption', 'CE1'))
q2.children.append(('caption', 'CE2'))
con.add(q1, 'AND')
con.add(q2, 'AND') obj = models.UserType.objects.filter(con)
from django.shortcuts import render,HttpResponse
from django import forms
from app01 import models
from django.db.models import F,Q
import time
from django.views.decorators.cache import cache_page
# Create your views here. class IndexForm(forms.Form):
# c = [
# (1, 'CEO'),
# (2, 'CTO')
# ]
# 静态字段,属于IndexForm类,即使数据库增加页面不会显示
c = models.UserType.objects.all().values_list('id','caption')
user_type_id = forms.IntegerField(widget=forms.Select(choices=c))
# 需要加上构造方法
def __init__(self, *args, **kwargs):
#父类构造方法:1.获取所有的静态字段 2.fields = []
super(IndexForm, self).__init__(*args, **kwargs)
#print(self.fields['user_type_id'].widget.choices)
self.fields['user_type_id'].widget.choices = models.UserType.objects.all().values_list('id','caption') def index(request):
# for i in range(10):
# models.UserType.objects.create(caption='CE'+str(i))
# c = models.UserType.objects.all().count()
# print(c)
form = IndexForm()
"""
q1 = Q()
q1.connector = 'OR'
q1.children.append(('id', 1))
q1.children.append(('id', 2))
q1.children.append(('id', 3)) obj = models.UserType.objects.filter(q1)
for item in obj:
print(item.id, item.caption)
"""
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(('caption', 'CE1'))
q2.children.append(('caption', 'CE2'))
con.add(q1, 'AND')
con.add(q2, 'AND') obj = models.UserType.objects.filter(con) for item in obj:
print(item.id, item.caption)
return render(request, 'index.html', {'form':form})

views.py

三、Model对多对操作

from django.db import models

# Create your models here.

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') #多对多
#自己创建
# class B2G(models.Model):
# b_id = models.ForeignKey('Boy')
# g_id = models.ForeignKey('Girl') # 1 小明
# 2 小黑
# 3 小军
class Boy(models.Model):
username = models.CharField(max_length=16) # 1 芳芳
# 2 珠珠
# 3 哈哈
class Girl(models.Model):
name = models.CharField(max_length=16)
#自动创建第三张表
b = models.ManyToManyField('Boy')

models.py

方式一:自己创建

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)

方式二:自动创建

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)
b1 = models.Boy.objects.get(id=1)
g1.b.add(b1) bs = models.Boy.objects.all()
g1.b.add(*bs)
g1.b.add(1)
g1.b.add(*[1,2,3,4,5,6,7]) 反向:
b1 = models.Boy.objects.get(id=1)
#因ManyToManyField所以隐含_set
b1.girl_set.add(1)
b1.girl_set.add(models.Girl.objects.all()) b1.girl_set.add(*[1,2,3,4,5])

删除:

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 = conection.cursor()
cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
row = cursor.fetchone()

四、中间件

配置文件:
MIDDLEWARE_CLASSES =
写类:
process_request
process_view
process_exception
process_response 1.10
配置文件:
MIDDLEWARE =
原版本:
如果process_request中有return,则所有的process_response执行一遍
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'md.sa.M1',
'md.sa.M2',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]

路径:/project_dir/md/sa.py

from django.utils import deprecation
class M1(deprecation.MiddlewareMixin):
def process_request(self, request):
print('M1.process_request') def process_view(self, request, callback, callback_args, callback_kwargs):
print('M1.process_view') def process_exception(self, request, exception):
print('M1.process_exception') def process_response(self, request, response):
print('M1.process_response')
return response def process_template_response(self, request, response):
print('M1.process_template_response') class M2(deprecation.MiddlewareMixin):
def process_request(self, request):
print('M2.process_request') def process_view(self, request, callback, callback_args, callback_kwargs):
print('M2.process_view') def process_exception(self, request, exception):
print('M2.process_exception') def process_response(self, request, response):
print('M2.process_response')
return response def process_template_response(self, request, response):
print('M2.process_template_response')

sa.py

def md(request):
print('views.md')
#return HttpResponse('ok')
obj = HttpResponse('OK')
#如果obj中有render方法则执行中间件的process_template_response
#render(request,'index.html')
#render_to_response('index')会执行process_template_response
return obj

五、缓存

6种方式:

1.开发调试
2.内存
3.文件
4.数据库
5.memcache缓存(python-memcached模块)
6.memcache缓存(pylibmc模块)
#单独页面缓存
#@cache_page(5)
def cache1(request):
c = time.time()
from Day20 import pizza_done
pizza_done.send(sender='seven', toppings=123, size=456)
return render(request, 'cache.html', {'c':c})
全站缓存
CACHES = {
'default':{
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR, 'cache')
}
}
{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ c }}</h1> <div style="border: 1px solid red; height: 50px;">
{% cache 5 views_h %}
<h1>{{ c }}</h1>
{% endcache %}
</div>
</body>
</html>

cache.html

六、信号

对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate from django.test.signals import setting_changed
from django.test.signals import template_rendered from django.db.backends.signals import connection_created def callback(sender, **kwargs):
print("xxoo_callback")
print(sender,kwargs) import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"]) def callback1(sender, **kwargs):
print("callback1")
print(sender, kwargs)
pizza_done.connect(callback1)

__init__.py

自定义信号:

a. 定义信号

import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

b. 注册信号

def callback(sender, **kwargs):
print("callback")
print(sender,kwargs) pizza_done.connect(callback)

c. 触发信号

from 路径 import pizza_done

pizza_done.send(sender='haha',toppings=456, size=789)

由于内置信号的触发者已经集成到Django中,所以其会自动调用,而对于自定义信号则需要开发者在任意位置触发。

七、自定义分页

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.pager a{
display: inline-block;
padding: 5px;
background-color: blue;
margin: 2px;
}
.pager a.active{
background-color: orangered;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>ID</th>
<th>名称</th>
</tr>
</thead>
<tbody>
{% for item in type_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.caption }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="pager">
{{ str_page }}
</div>
</body>
</html>

page.html

def page(request):
# for i in range(25, 100):
# models.UserType.objects.create(caption='CO'+str(i))
current_page = request.GET.get('p',1)
current_page = int(current_page)
#每页显示10条数据
#第一页0,10
start = (current_page - 1) * 10
end = current_page * 10
type_list = models.UserType.objects.all()[start:end]
#将所有的页码显示在页面上
total_item = models.UserType.objects.all().count()
a,b = divmod(total_item, 10)
if b == 0:
pass
else:
a = a + 1
list_page = []
if current_page <= 1:
prev = "<a href='javascript:void(0);'>上一页</a>"
else:
prev = "<a href='/page?p=%s'>上一页</a>" % (current_page-1,)
list_page.append(prev)
for i in range(1,a+1):
if i == current_page:
temp = "<a class='active' href='/page?p=%s'>第%s页</a>" % (i, i,)
else:
temp = "<a href='/page?p=%s'>第%s页</a>" % (i,i,)
list_page.append(temp)
str_page = ''.join(list_page)
from django.utils.safestring import mark_safe
str_page = mark_safe(str_page)
return render(request, 'page.html', {'type_list':type_list, 'str_page': str_page})

views.py

详见武sir博客:http://www.cnblogs.com/wupeiqi/articles/5246483.html