zoukankan      html  css  js  c++  java
  • 19 Jul 18 Django-Admin

    19 Jul 18

    一、计划

    1 CRM

       stark组件(一周)

       权限,CRM (3天)

     

    2 路飞

      restframework (2-3天)

      vue-cli

      luffy之支付系统,redis (一周)

     

    3 爬虫

     

    4 flask

     

    5 linux

     

    二、Django回顾

    1 url控制器+MTV

     

    2 Ajax

      a. ContentType(详见item 7)

     

    3 forms组件

     

    4 cookie,session

      def foo(request):

        request.session["name"]="egon"

        return balabala

     

    5 用户认证组件

     

    6 中间件

      a. cookie/session 和url的中间件很重要,要看源码

     

    7 ContentType (请求体的编码类型)(*******)

      https://www.cnblogs.com/yuanchenqi/articles/9070966.html

      a. application/x-www-form-urlencoded

         1)在form和ajax提交POST请求时,如果不特意指定enctype(form)或contentType(ajax),默认使用的编码类型

         2)请求体:user=yuan&age=22;浏览器在解析请求头时,查看到编码类型,然后在用该编码类型对应的请求体数据样式,将数据进行相应提取展示

         3) 请求格式

            "

            POST /index  HTTP/1.1

           contentType:application/x-www-form-urlencoded

     

            name=yuan&pwd=123

            "

     

      b. multipart/form-data

         1) 使用表单上传文件时,必须让<form> 表单的enctype 等于multipart/form-data

     

      c. text/plan

         1) form表单只支持以上三种contentType(application/x-www-form-urlencoded,multipart/form-data,ext/plan),不支持application/json等

         2) text/pam基本上不被使用

     

      d. application/json

         1) request.POST只解析application/x-www-form-urlencoded;即如果用application/json编码格式提交数据,print(request.POST)为空。

         2)处理该情况,可以从request.body(为经处理的原始数据,bytes类型)中提取数据

     

      e. 用ajax发送json数据时,两种处理数据的方式

         1) 在html中用application/json这种contentType发送json格式数据,在views中从request.body中提取数据(解码,loads)

            d=json.loads(request.body.decode("utf8"))

         2)在html中依据用默认的contentType(application/x-www-form-urlencoded)发送数据,但做如下处理

            data:{xxx:JSON.stringify({a:1,b:2})},

     

    8 如果有传来多个数据(checkbox,select multiple),用getlist取出相应数据

      a. checkbox

      <input type="text" name="user" value="yuan">

      <input type="checkbox" name="hobby" value="1"> 篮球

      <input type="checkbox" name="hobby" value="2"> 足球

      <input type="checkbox" name="hobby" value="3"> 彩色球

     

      b. select multiple

      <select multiple name="xxx">

         <option value="1">111</option>

         <option value="2">222</option>

         <option value="3">333</option>

      </select>

     

      c. 请求体格式

         user=yuan&hobby=[1,2,3]&xxx=[1,2,3]

     

      d. 在Django的views中取出相应数据

        request.POST.get("user")

         request.POST.getlist("hobby")

     

    9 Others

      a. Django中response的一定是HttpResponse中的一类(HttpResponse,JsonResponse,render,redirect)

      b. Django一般比较适合大项目,而flask一般比较适合小精型项目

      c. request.meta :封装了请求头信息的字典

      d. wsgiref, 收发消息;将字符串封装成request对象,将response对象转换成字符串

      e. 浏览器只能识别HTML, CSS, JS

     

    三、admin的使用

    https://www.cnblogs.com/yuanchenqi/articles/8323452.html

    1 Admin:Django下的后台数据管理的web页面

      # 每个注册过的表对应四个url

       http://127.0.0.1:8000/admin/app01/publish/

       http://127.0.0.1:8000/admin/app01/publish/add/

       http://127.0.0.1:8000/admin/app01/publish/1/change/

       http://127.0.0.1:8000/admin/app01/publish/1/delete/

     

    2 admin的定制

      a 方法

        1) 方法一

        class UserAdmin(admin.ModelAdmin):

            list_display = ('user', 'pwd',)

     

        admin.site.register(models.UserInfo, UserAdmin)  # 第一个参数可以是列表

     

        2)方法二

       @admin.register(models.UserInfo) # 第一个参数可以是列表

        class UserAdmin(admin.ModelAdmin):

            list_display = ('user', 'pwd',)

     

      b 可定制的功能

        1)list_display: 列表时,定制显示的列。

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            list_display = ('user', 'pwd', 'xxxxx')

     

            def xxxxx(self, obj):

                return "xxxxx"

     

        2)list_display_links:列表时,定制列可以点击跳转。

        @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            list_display = ('user', 'pwd', 'xxxxx')

            list_display_links = ('pwd',)

     

        3)list_filter:列表时,定制右侧快速筛选。

           # 一般用于一对多或多对多关系中

     

        4)list_select_related:列表时,连表查询是否自动select_related

     

        5)list_editable:列表时,可以编辑的列

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            list_display = ('user', 'pwd','ug',)

            list_editable = ('ug',)

     

        6)search_fields:列表时,模糊搜索的功能

           #列表中可以排多个值,是一种或的关系

        @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

     

            search_fields = ('user', 'pwd')

     

        7)date_hierarchy:列表时,对Date和DateTime类型进行搜索

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

     

            date_hierarchy = 'ctime'

     

        8)inlines:详细页面,如果有其他表和当前表做FK,那么详细页面可以进行动态增加和删除

        class UserInfoInline(admin.StackedInline): # TabularInline

            extra = 0

            model = models.UserInfo

     

        class GroupAdminMode(admin.ModelAdmin):

            list_display = ('id', 'title',)

            inlines = [UserInfoInline, ]

     

        9)action:列表时,定制action中的操作;通过定制批量处理函数

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

     

            # 定制Action行为具体方法

            def func(self, request, queryset):

                print(self, request, queryset)

               print(request.POST.getlist('_selected_action'))

     

            func.short_description = "中文显示自定义Actions"

            actions = [func, ]

     

            # Action选项都是在页面上方显示

            actions_on_top = True

            # Action选项都是在页面下方显示

            actions_on_bottom = False

     

            # 是否显示选择个数

           actions_selection_counter = True

     

        10)定制HTML模板

        add_form_template = None

        change_form_template = None

        change_list_template = None

       delete_confirmation_template = None

        delete_selected_confirmation_template = None

        object_history_template = None

     

        11)raw_id_fields:详细页面,针对FK和M2M字段变成以Input框形式

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

     

            raw_id_fields = ('FK字段', 'M2M字段',)

     

        12)fields:详细页面时,显示字段的字段

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            fields = ('user',)

     

        13)exclude:详细页面时,排除的字段

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            exclude = ('user',)

     

        14)readonly_fields:详细页面时,只读字段

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            readonly_fields = ('user',)

     

        15)fieldsets:详细页面时,使用fieldsets标签对数据进行分割显示

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            fieldsets = (

                ('基本数据', {

                    'fields': ('user', 'pwd', 'ctime',)

                }),

                ('其他', {

                    'classes': ('collapse', 'wide', 'extrapretty'),  # 'collapse','wide', 'extrapretty'

                    'fields': ('user', 'pwd'),

                }),

            )

     

        16)详细页面时,M2M显示时,数据移动选择(方向:上下和左右)

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)

     

        17)ordering:列表时,数据排序规则

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            ordering = ('-id',)

            或

            def get_ordering(self, request):

                return ['-id', ]

     

        18)radio_fields:详细页面时,使用radio显示选项(FK默认使用select)

     

        radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL

     

        19)form = ModelForm:用于定制用户请求时候表单验证

        from app01 import models

        from django.forms import ModelForm

        from django.forms import fields

     

        class MyForm(ModelForm):

            others = fields.CharField()

     

            class Meta:

                model = models = models.UserInfo

                fields = "__all__"

     

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

     

            form = MyForm

     

        20)empty_value_display = "列数据为空时,显示默认值"

       @admin.register(models.UserInfo)

        class UserAdmin(admin.ModelAdmin):

            empty_value_display = "列数据为空时,默认显示"

     

            list_display = ('user','pwd','up')

     

            def up(self,obj):

                return obj.user

            up.empty_value_display = "指定列数据为空时,默认显示"

     

    四、admin的源码

    https://www.cnblogs.com/yuanchenqi/articles/8323452.html

    1 复习单例

      单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

      比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建AppConfig 对象的实例,这就导致系统中存在多个AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

      在Python 中,我们可以用多种方法来实现单例模式:

     

      a 使用__new__

        class Singleton(object):

            _instance = None

            def __new__(cls, *args, **kw):

                if not cls._instance:

                    cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)

                return cls._instance

     

        class MyClass(Singleton):

            a = 1

     

      b 使用装饰器(decorator)

      import settings

      def singleton(cls): #cls=Mysql

         _instance=cls(settings.HOST,settings.PORT)

     

          def wrapper(*args,**kwargs):

              if args or kwargs:

                 obj=cls(*args,**kwargs)

                  return obj

              return _instance

     

          return wrapper

     

      @singleton # Mysql=singleton(Mysql)

      class Mysql:

          def __init__(self,host,port):

              self.host=host

              self.port=port

     

      obj1=Mysql()

      obj2=Mysql()

      obj3=Mysql()

      print(obj1 is obj2 is obj3) #True

     

      obj4=Mysql('1.1.1.3',3307)

      obj5=Mysql('1.1.1.4',3308)

      print(obj3 is obj4) #False

     

      c 使用元类(metaclass)

      import settings

      class Mymeta(type):

          def __init__(self,name,bases,dic): #定义类Mysql时就触发

              # 事先先从配置文件中取配置来造一个Mysql的实例出来

              self.__instance = object.__new__(self)  # 产生对象

             self.__init__(self.__instance, settings.HOST, settings.PORT)  # 初始化对象

              # 上述两步可以合成下面一步

              # self.__instance=super().__call__(*args,**kwargs)

     

             super().__init__(name,bases,dic)

     

          def __call__(self, *args, **kwargs): #Mysql(...)时触发

              if args or kwargs: # args或kwargs内有值

                 obj=object.__new__(self)

                 self.__init__(obj,*args,**kwargs)

                  return obj

     

              return self.__instance

     

      class Mysql(metaclass=Mymeta):

          def __init__(self,host,port):

              self.host=host

              self.port=port

     

      obj1=Mysql() # 没有传值则默认从配置文件中读配置来实例化,所有的实例应该指向一个内存地址

      obj2=Mysql()

      obj3=Mysql()

     

      print(obj1 is obj2 is obj3)

      obj4=Mysql('1.1.1.4',3307)

     

      d 定义一个类方法实现单例模式

      import settings

      class Mysql:

          __instance=None

          def __init__(self,host,port):

              self.host=host

              self.port=port

     

          @classmethod

          def singleton(cls):

              if not cls.__instance:

                 cls.__instance=cls(settings.HOST,settings.PORT)

              return cls.__instance

     

      obj1=Mysql('1.1.1.2',3306)

      obj2=Mysql('1.1.1.3',3307)

      print(obj1 is obj2) #False

     

      obj3=Mysql.singleton()

      obj4=Mysql.singleton()

      print(obj3 is obj4) #True

     

      e 使用模块

        Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成.pyc 文件,当第二次导入时,就会直接加载.pyc 文件,而不会再次执行模块代码。

        因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:

     

        # mysingleton.py

        class My_Singleton(object):

            def foo(self):

                pass

        my_singleton = My_Singleton()

     

        # 使用

        from mysingleton import my_singleton

        my_singleton.foo()

     

        注意:

        1)在同一django中的不同py文件中导入变量my_singleton为同一单例

        2)在同一django中的不同py文件中导入类My_singleton为同一个类,但调用其产生的对象为不同的对象

     

    2 复习类/对象中属性的查找

     

     

    3 启动

      循环加载执行所有已经注册的app中的admin.py文件

      def autodiscover():

         autodiscover_modules('admin', register_to=site)

     

    4 注册(*******)

      class AdminSite(object):

          def __init__(self, name='admin'):

              self._registry = {}

          def register(self, model_or_iterable, admin_class=None, **options):

              if not admin_class:

                  admin_class = ModelAdmin   # 配置类

     

             self._registry[model] = admin_class(model, self)

     

              # {Book:BookConfig(Book),Publish:ModelAdmin(Publish)}

     

      site=AdminSite()   # 对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象

     

     -----------------------------------------

      class BookConfig(ModelAdmin):

         list_display=["",]

     

     admin.site.register(Book,BookConfig) # Book在app01中

     admin.site.register(Publish)  # Publish在app02中;按照注册顺序,先执行app01中的admin,再执行app02中的admin

     

     -----------------------------------------

      print(admin.site._registry)

      {

      <class 'django.contrib.auth.models.Group'>: <django.contrib.auth.admin.GroupAdmin object at 0x00000256B97EF9E8>,

      <class 'django.contrib.auth.models.User'>: <django.contrib.auth.admin.UserAdmin object at 0x00000256B9825438>,

      <class 'app01.models.Book'>: <app01.admin.BookConfig object at 0x00000256B983C080>,

      <class 'app01.models.Publish'>: <app01.admin.PublishConfig object at 0x00000256B983C128>

      }

      # 两个django自带的键值对,外加两个app中各自注册的键值对(model:对应配置类的对象)

  • 相关阅读:
    yarn 集群任务全部pending 事件记录
    flink 在使用upsert_kafka connector 时报错,找不到类Exeption: Could not find any factory for identifier 'upsert-kafka' that implements 'org.apache.flink.table.factories.DynamicTableFactory' in the classpath.
    SpringBoot 项目无法启动,且无任何日志
    Python之PyQt编程
    转:redis 节约内存之Instagram的Redis实践
    云计算 私有云 公有云 混合云
    java 类继承估计99%的人都不知道的问题?
    Java Vector 类
    Java LinkedList 类
    Java Queue 接口
  • 原文地址:https://www.cnblogs.com/zhangyaqian/p/py20180719.html
Copyright © 2011-2022 走看看