zoukankan      html  css  js  c++  java
  • Django之信号和序列化

     

    前言

    Django的信号要从一张抽象图和一个需求说起;

    赛道:Django

    赛车:http请求

    基础设施:Django设置的信号

    一、Django内置信号类型

    1、既然赛道上有各种基础设置,那么Django里面又内置了哪些信号呢?

    Model signals
        pre_init                    # django的modal执行其构造方法前,自动触发
        post_init                   # django的modal执行其构造方法后,自动触发
        pre_save                    # django的modal对象保存前,自动触发
        post_save                   # django的modal对象保存后,自动触发
        pre_delete                  # django的modal对象删除前,自动触发
        post_delete                 # django的modal对象删除后,自动触发
        m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
        class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发



    Management signals pre_migrate # 执行migrate命令前,自动触发 post_migrate # 执行migrate命令后,自动触发


    Request/response signals request_started # 请求到来前,自动触发 request_finished # 请求结束后,自动触发 got_request_exception # 请求异常后,自动触发


    Test signals setting_changed # 使用test测试修改配置文件时,自动触发 template_rendered # 使用test测试渲染模板时,自动触发


    Database Wrappers connection_created # 创建数据库连接时,自动触发

    2、需求:如何在每次数据库添加操作之后,记录一条行为日志呢?

    切入点:post_save # django的modal对象保存后,自动触发(Django的orm在执行create操作,内部也会执行save方法)

    3、见识了信号之后疑惑信号和中间件的区别?

    中间件只是能设置在Django的出口和入口,而中间件散步较广;

    二、应用信号

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

    1、导入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

    2、注册信号

    为了确保你的程序在启动后就会导入和注册信号,一定要放在Django程序目录的__init__.py文件里

    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(sender)                    #操作的那张表
        print(kwargs['instance'].name)  #获取增加的那样记录的 name
    
    
    pre_save.connect(callback)
    View Code

    二、自定义信号

    如果Django自定制的信息无法满足你的需求还可以自定制信号

    1.定义注册

    # 自定义信号
    import django.dispatch
    pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
    def callback1(sender,**kwargs):
        print('这是一个自定义信号')
        print(sender)                    #操作的那张表
        print(kwargs)                #获取增加的那样记录的 
    
    pizza_done.connect(callback1)

    2、导入执行

    def index(request):
        userlist=models.UserInfo.objects.all()
        ctime=time.time()
        from django缓存 import pizza_done
        a=models.UserInfo.objects.create(name='xxx',pwd='123')
        pizza_done.send(sender=a.name,pwd=a.pwd) #调用自定义信号必须传sender参数
        return render(request,'index.html',locals())

    三、序列化

    json模块默认能处理的Python数据类型有限,在使用Django做web开发的时候如何 序列化 query_set和时间数据类型呢?

    +---------------+-------------------+
    | JSON | Python |
    +===============+===================+
    | object | dict |
    +---------------+-------------------+
    | array | list |
    +---------------+-------------------+
    | string | str |
    +---------------+-------------------+
    | number (int) | int |
    +---------------+-------------------+
    | number (real) | float |
    +---------------+-------------------+
    | true | True |
    +---------------+-------------------+
    | false | False |
    +---------------+-------------------+
    | null | None |
    +---------------+--------------

    如何破解?

    1、serializers(Django自带的序列化工具)
    from django.core import serializers
    def
    index(request): userlist=models.UserInfo.objects.all() # 方案1 userlist_str=serializers.serialize('json',userlist) print(userlist_str) ctime=time.time()

    2、自定制  json.dumps方法中cls参数(serializers内部也是这样实现的

    vale=json.dumps(userlist,cls=json.JSONEncoder)
    from datetime import datetime
    from datetime import date
    import json
    #自定义一个类,由于Python的一数据类型,json可以序列化,所有可以继承json.JSONEncoder方法
    class JsonCustomEncoder(json.JSONEncoder):
        def default(self, field):
    
            if isinstance(field, datetime):
                return field.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(field,date ):
                return field.strftime('%Y-%m-%d')
            else:
                return json.JSONEncoder.default(self, field)
    data_list=[
        {'name':'eric0','age':18,'ctime':datetime.now()},
        {'name':'eric1','age':18,'ctime':datetime.now()},
        {'name':'eric2','age':18,'ctime':datetime.now()}
    ]
    
    str1=json.dumps(data_list, cls=JsonCustomEncoder)
    print(str1)
     
  • 相关阅读:
    nginx.conf nginx反向代理配置文件
    linux shell date的用法
    shell find 命令 find命令报错 find: paths must precede expression:
    nginx平滑升级
    centos 6/7 tar包安装mysql 5.7
    3. Longest Substring Without Repeating Characters
    模板之类模板2
    排序之归并排序
    排序之堆排序
    排序之选择排序
  • 原文地址:https://www.cnblogs.com/sss4/p/7569680.html
Copyright © 2011-2022 走看看