zoukankan      html  css  js  c++  java
  • Django-自定义增删改查组件的一些体会

    1.路由系统

    namespace,用于区分相同name的url,通过namespace为url添加一个前缀

    反向生成URL的时候

    reverse('namespace:name')
    {% url "namespace:name"%}
        @property
        def urls(self):
            return (self.get_urls(), None, 'stark')
     # 总的url
        def get_urls(self):
            model_class_app = (self.model_class._meta.app_label, self.model_class._meta.model_name)
            urlpatterns = [
                url(r'^$', self.wrap(self.changlist_view), name='%s_%s_changelist' % model_class_app),
                url(r'^add/$', self.wrap(self.add_view), name='%s_%s_add' % model_class_app),
                url(r'^(d+)/change/$', self.wrap(self.chang_view), name='%s_%s_change' % model_class_app),
                url(r'^(d+)/delete/$', self.wrap(self.delete_view), name='%s_%s_delete' % model_class_app)
            ]
            urlpatterns.extend(self.extra_url())
            return urlpatterns
    
        # 额外的url 在自己的config中定义该函数添加
        def extra_url(self):
            return []
    
        @property
        def urls(self):
            return self.get_urls()
    
        # 列表页面的url
        def get_list_url(self):
            name = 'stark:%s_%s_changelist' % (self.model_class._meta.app_label, self.model_class._meta.model_name)
            list_url = reverse(name)
            return list_url
    
        # 添加按钮的url
        def get_add_url(self):
            name = 'stark:%s_%s_add' % (self.model_class._meta.app_label, self.model_class._meta.model_name)
            add_url = reverse(name)
            return add_url
    
        # 编辑的url
        def get_change_url(self, nid):
            name = 'stark:%s_%s_change' % (self.model_class._meta.app_label, self.model_class._meta.model_name)
            edit_url = reverse(name, args=(nid,))
            return edit_url
    
        # 删除的url
        def get_delete_url(self, nid):
            name = 'stark:%s_%s_delete' % (self.model_class._meta.app_label, self.model_class._meta.model_name)
            del_url = reverse(name, args=(nid,))
            return del_url

    2. 制作项目启动时,自动加载文件

    在当前app下的apps中写入下面代码即可,并去已注册的所有app中,找stark.py文件,并加载

    def ready(self):
                from django.utils.module_loading import autodiscover_modules
                autodiscover_modules('stark')

    3.model操作

    model.UserInfo
            model.UserInfo._meta.app_label#获取当前app的名称
            model.UserInfo._meta.model_name#获取当前类名小写
            model.UserInfo._meta.get_field('username')#获取字段
            
            model.UserInfo._meta.get_field('username').verbose_name#获取verbose_name
            model.UserInfo._meta.get_field('外键或多对多字段').rel.to #得到关联的model类

            - models.UserInfo._meta.get_field('name') # 根据字段名称,获取字段对象
            - models.UserInfo._meta.fields # 获取类中所有的字段
            - models.UserInfo._meta._get_fields() # 获取类中所有的字段(包含反向关联的字段)
            - models.UserInfo._meta.many_to_many # 获取m2m字段

     

    4.函数和方法

    函数还是方法

    对于类中的函数,直接用类名调用的话需要传入self参数,既函数

                                 用对象调用的话就不需要传入self参数,既方法

    class Foo(object):
                    def __init__(self):
                        self.name = 'alex'
                    def func(self):
                        print(self.name)
    
                from types import FunctionType,MethodType
    
                obj = Foo()
                print(isinstance(obj.func,FunctionType)) # False
                print(isinstance(obj.func,MethodType))   # True
    
                print(isinstance(Foo.func,FunctionType)) # True
                print(isinstance(Foo.func,MethodType))   # False
                """
                注意:
                    方法,无需传入self参数
                    函数,必须手动传入self参数
                """
    函数是一个对象,
                - func.__name__  #获取函数的名字
                - func.text = "sdfsfd"  #设置属性值
    # obj = Foo()
    # print(obj.func) # <bound method Foo.func of <__main__.Foo object at 0x00000000021E8400>>
    
    # print(Foo.func)  # <function Foo.func at 0x0000000001E89B70>
    #
    # obj = Foo()
    # Foo.func(obj)
    #
    # obj = Foo()
    # obj.func()
    class Foo(object):
        def __init__(self):
            self.name = 'alex'
        def func(self):
            print(self.name)
    
    from types import FunctionType,MethodType
    
    obj = Foo()
    print(isinstance(obj.func,FunctionType)) # False
    print(isinstance(obj.func,MethodType))   # True
    
    print(isinstance(Foo.func,FunctionType)) # True
    print(isinstance(Foo.func,MethodType))   # False
    """
    注意:
        方法,无需传入self参数
        函数,必须手动传入self参数
    """

    5.保留搜索条件的两种方法

    方式一 直接通过 request.GET.urlencode()

        列表页面:
                    获取当前所有条件,添加到 
                        - 编辑按钮的URL后面
                        - 添加按钮的URL后面
                编辑或添加页面:
                    - POST提交时,获取原来列表页面传过来的条件
                    - 拼接URL  /hosts/?原来的条件
                    
                list页面:
                
                list_condition = request.GET.urlencode()
                
                    {% for item in host_list %}
                        <li>{{ item }} <a href="/edit/54/?{{ list_condition }}">编辑</a></li>
                    {% endfor %}
                    
                add/edit页面:http://127.0.0.1:8000/edit/10/?page=5&id__gt=4
                    def edit_host(request,pk):
                        if request.method == "GET":
                            return render(request,'edit_host.html')
                        else:
                            # 修改成功 /hosts/?page=5&id__gt=4
                            url = "/hosts/?%s" %(request.GET.urlencode())
                            return redirect(url)

    方式二

        list页面: http://127.0.0.1:8000/hosts/?page=5&id__gt=4
                
                    params = QueryDict(mutable=True)
                    params['_list_filter'] = request.GET.urlencode()
                    list_condition = params.urlencode()
                    
                    
                    {% for item in host_list %}
                        <li>{{ item }} <a href="/edit/54/?{{ list_condition }}">编辑</a></li>
                    {% endfor %}
        
                add/edit页面:http://127.0.0.1:8000/edit/54/?_list_filter=page%3D5%26id__gt%3D4
                    
                    def edit_host(request,pk):
                    if request.method == "GET":
                        return render(request,'edit_host.html')
                    else:
                        # 修改成功 /hosts/?page=5&id__gt=4
                        url = "/hosts/?%s" %(request.GET.get('_list_filter'))
                        return redirect(url)
    request.GET本质是QuerySet,不能改变但是给他设置
    
    request.GET._mutable=True就可以改变了,但是不建议改变request.GET
    
    我们可以自定义
    params = QueryDict(mutable=True)或者
    import copy
    params=copy.deepcopy(request.GET)
    - request.GET
            - ?name=alex&age=18&age=19
            - params = { name:['alex', ], age:[18,19] }
            
            - params['hobby'] = "鲁宁"#实际上是一个列表
            - params = { name:['alex', ], age:[18,19], hobby:[ 鲁宁,] }
            
            - params.setlist('hobby',["鲁宁"])
            - params = { name:['alex', ], age:[18,19], hobby:[鲁宁,] }
    类似的还有
    pop()
    remove()方法
    用法和字典一样

    6.Q函数的补充

    - Q 
                - Q(id__gt=1)|Q(id=2)
                - con = Q()
            - 模板语言中的字典,不能以_开头   obj._
            - GET请求
            
            con = Q()
    
            q1 = Q()
            q1.connector = 'or'
            q1.children.append( ('name','alex1') )
            q1.children.append( ('name','alex2') )
    
            q2 = Q()
            q2.children.append( ('age__gt',18))
            q2.children.append( ('id__gt',18))
    
            con.add(q1,'OR')
            con.add(q2,'OR')
            # (name='alex' or name=='alex2') or (age>18 and id > 18)
    
            queryset = self.model_class.objects.filter(con)

    7.一个对象是否可以被for循环?

        class Foo(object):
                    def __init__(self,name,data_list):
                        self.name = name
                        self.data_list = data_list
    
                    def __iter__(self):
                        yield "<div>"
                        yield "全部"
                        for item in self.data_list:
                            yield item
                        yield "</div>"
                obj_list = [Foo('富贵',['','']), Foo('强哥',['啊啊','问问']), Foo('熊平',['搜索','所属'])]
    
    
                for obj in obj_list:
                    for item in obj:
                        print(item)

    # 需求:循环对象时,先打印对象name属性,然后再答应123。

    class A(object):
        def __init__(self,name,data_list):
            self.name=name
            self.data_list=data_list
    
        def __iter__(self):
            yield self.name
            for i in self.data_list:
                yield i
    
    
    
    obj_list=[A('ctz',[1,2,3]),A('aa',[1,2,3]),A('bb',[1,2,3]),A('cc',[1,2,3])]
    
    for obj in obj_list:
        for item in obj:
            print(item)

    8.里面用了很多yield 记住

    9.isinstance

    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    obj = Bar()
    
    # isinstance用于判断,对象是否是指定类的实例 (错误的)
    # isinstance用于判断,对象是否是指定类或其派生类的实例
    print(isinstance(obj,Foo))
    print(isinstance(obj,Bar))
    
    
    print(type(obj) == Bar)
    print(type(obj) == Foo)
    
    
    #type  精确判断
    # 对象,判断是否是某个类型? type,isinstance
    
    from django.forms.models import ModelChoiceField
    from django.forms.models import ModelMultipleChoiceField
    
    isinstance(obj,ModelChoiceField)

    10.反射补充

    1.常用 普通

    class Foo(object):
        def func(self):
            pass
    
    obj = Foo()
    
    name = "func"
    
    fc = getattr(obj,name)
    
    fc()

    2.补充的 django setting.py中中间件注册(参考django源码得知)

    class SqlServerHelper(object):
        def fetchone(self):
            """
            链接SQLServer,获取一条数据
            :return: 
            """
            print('SQLServer.fetchone')
    sqlserver.py
    class MySQLHelper(object):
    
        def fetchone(self):
            """
            链接MySQL,获取一条数据
            :return: 
            """
            print('MySQL.fetchone')
    mysql.py
    # DB_PATH = "db.mysql.MySQLHelper"
    DB_PATH = "db.sqlserver.SqlServerHelper"
    settings.py
    from 反射.settings import DB_PATH
    
    def func():
        # 导入文件
        # 反射
        # DB_PATH = "db.mysql.MySQLHelper"
        module_path,cls_name = DB_PATH.rsplit('.',maxsplit=1)
    
        # 以字符串的形式导入模块
        # from db import mysql
        import importlib
        module_obj = importlib.import_module(module_path)
    
        # 去模块中导入类
        cls = getattr(module_obj,cls_name)
    
        # 类实例化
        obj = cls()
        obj.fetchone()
    
    
    if __name__ == '__main__':
        func()
    app.py

     11、对象加减乘除

    加法

    class Foo(object):
                    
                    def __init__(self,age):
                        self.age = age
                        
                    def __add__(self, other):
                        # return self.age + other.age
                        return Foo(self.age + other.age)
                        
                obj1 = Foo(19)
                obj2 = Foo(18)
    
                obj3 = obj1 + obj2

    其他方法也有对应的方法 直接调用仿照上面即可

  • 相关阅读:
    mysql u root p 等这些常用的参数
    关于类对象大小的 sizeof 计算问题
    sql like用法
    链表队列
    Zend Studio安装教程
    #define和inline 的区别
    ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)
    Ubuntu 10.04下LAMP环境的配置与使用教程
    win7保护视力的电脑设置
    sql between and 用法
  • 原文地址:https://www.cnblogs.com/ctztake/p/8076003.html
Copyright © 2011-2022 走看看