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

转载于:https://www.cnblogs.com/icsnow/p/6037782.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值