zoukankan      html  css  js  c++  java
  • stark 增删改

    • 优雅装饰器
    import functools
    
    def wrapper(func):
        @functools.wraps(func)
        # 保留原函数的信息
        def inner(*args, **kwargs):
            return func(*args, **kwargs)
        return inner
    @wrapper
    def f1():
        print('f1')
    
    @wrapper
    def f2():
        print('f1')
    
    print(f1.__name__)
    print(f2.__name__)
    """
    之前
    inner
    inner
    """
    
    
    """
    之后
    f1
    f2
    """
    装饰器保留原函数的信息

    • 判断是函数,还是变量
        判断arg是函数则打印1,arg是方法则打印2
    from types import MethodType,FunctionType
    def check(arg):
        """
        判断arg是函数则打印1,arg是方法则打印2
        :param arg:
        :return:
        """
        if isinstance(arg,MethodType):
            print(2)
        elif isinstance(arg,FunctionType):
            print(1)
        else:
            print('不认识')
    
    def func():
        pass
    
    class Foo(object):
        def display(self):
            pass
    
    check(func)
    check(Foo.display)
    check(Foo().display)
    
    """
    1
    1
    2
    """
    from types import MethodType,FunctionType

    • 类传变量的一种方式

       实例方法传参,要传实例对象本身

    class RoleConfig(object):
    
        def f1(self, arg):
            print('f1', arg)
    
        def f2(self, arg):
            print('f2', arg)
    
        list_display = [f1, f2]
    
    
    obj = RoleConfig()
    for item in RoleConfig.list_display:
        item(obj, 2)
     # obj就是self,实例变量本身
        # 传变量的一种方式
    
    view


    • 利用列表储存函数对象
       一个进程两次调用类变量
    class RoleConfig(object):
    
        def f1(self, arg):
            print('f1', arg)
    
        def f2(self, arg):
            print('f2', arg)
    
        def f3(self, arg):
            print('f3', arg)
    
        list_display = [f1, f2]
    
        def get_list_display(self):
            self.list_display.insert(0, RoleConfig.f3)
            return self.list_display
    obj1 = RoleConfig()
    for item in obj1.get_list_display():
        item(obj1, 2)   # 刚开始这时候列表里还没有,加进f3,
    
    obj2 = RoleConfig()
    for item in obj2.get_list_display():
        print('obj2----')
        item(obj2, 6)   # 这时候列表里有了f3,再插入一个f3反回。所以此处列表里有四个
    
    
    # 利用类的变量列表,储存对象
    # 一个进程对类操作了两次
    """
    f3 2
    f1 2
    f2 2
    f3 6
    f3 6
    f1 6
    f2 6
    """
    view
    class RoleConfig(object):
    
        def f1(self, arg):
            print('f1', arg)
    
        def f2(self, arg):
            print('f2', arg)
    
        def f3(self, arg):
            print('f3', arg)
    
        list_display = [f1, f2]
    
        def get_list_display(self):
            v = []
            v.extend(self.list_display)
            v.insert(0, RoleConfig.f3)
            return v
    
    
    obj1 = RoleConfig()#[f1,f2]
    for item in obj1.get_list_display():# [f3,f1,f2]
        item(obj1, 2)
    
        print('---------------')
        obj2 = RoleConfig()#[f1,f2]
        for item in obj2.get_list_display(): #[f3,f1,f2]
            item(obj2, 6)
        print('+++++')
    
    """
    f3 2
    ---------------
    f3 6
    f1 6
    f2 6
    +++++
    f1 2
    ---------------
    f3 6
    f1 6
    f2 6
    +++++
    f2 2
    ---------------
    f3 6
    f1 6
    f2 6
    +++++
    """
    
    view


    • 利用yield取数据
    不要一次性取出来,占内存
       以前的:
          def func(request):
             result = []
    
             data_list = models.Users.objects.all()
             for row in data_list:
                temp = "%s%s" (row.name,row.pwd,)
                result.append(temp)
    
             return render(request,'xxx.html',{'result':result})
    
          xxx.html
    
             {% for row in result %}
                {{row}}
             {% endfor%}
    
       现在的:
    
          def get_result(data_list):
             for row in data_list:
                temp = "%s%s" (row.name,row.pwd,)
                yield temp
    
          def func(request):
    
             data_list = models.Users.objects.all()
             result = get_result(data_list)
    
             return render(request,'xxx.html',{'result':result})
    
          xxx.html
             {# 生成器,不断去调用#}
             {% for row in result %}
                {{row}}
             {% endfor%}
    view


    复选框实现

    • 复选框函数 mark_safe
    def display_checkbox(self, row=None, header=False):
        # 选择框功能             默认None,表头   如果是表头,则显示相应字段
        if header:
            return "选择"  # 表头第一个字段,可以自定制
        return mark_safe("<input type='checkbox' name='pk' value='%s' />" % row.pk)
        #     安全渲染****                                   选中行数据pk
    view
    • 复选框函数实现与显示

    调用复选框函数,拿到标签渲染

    def changelist_view(self, request):
        # 所有URL的查看列表页面
        # 获取表所有数据
        queryset = self.model_class.objects.all().order_by(*self.get_order_by())
    
        # 要显示的字段
        list_display = self.list_display
    
        header_list = []  # 表头列表
        if list_display:  # 判断有没有显示字段
            for name_or_func in list_display:
                if isinstance(name_or_func, FunctionType):  # 判断是不是函数,是则执行
                    verbose_name = name_or_func(self, header=True)
                else:  # 不是函数,则按规则去取字段的名称
                    verbose_name = self.model_class._meta.get_field(name_or_func).verbose_name
                header_list.append(verbose_name)
        else:  # 没有显示字段列表,取表名作为表头
            header_list.append(self.model_class._meta.model_name)
    
        body_list = []  # 表体列表
        for row in queryset:  # 从查找到的queryset对象里取
            row_list = []  # 行列表
            if not list_display:  # 没有规定显示的字段
                row_list.append(row)  # 直接将一条queryset 放到行列表里面
                body_list.append(row_list)  # 再放到表体
                continue
            for name_or_func in list_display:  # 按照要显示的字段,取数据,遇到函数就执行显示复选框,并返回该行对象
                if isinstance(name_or_func, FunctionType):  # 判断是否是功能函数
                    val = name_or_func(self, row=row)  # 执行函数反回功能内容
                else:  # 其他字段的数据正常取
                    val = getattr(row, name_or_func)  # getattr 映射 每个要显示字段名 ,取queryset里面的字段值
                row_list.append(val)  # 添加到行
            body_list.append(row_list)  # 添加到表体
        #  反回渲染页面
        return render(request, 'stark/changelist.html', {'header_list': header_list, 'body_list': body_list})
    
    view
    • 前端页面

        循环取值

    <div>
        <table class="table table-bordered"> {# 基于bootstrap 创建table表 #}
            <thead>  {# 表头 #}
                <tr>
                    {% for item in header_list %}
                    <th>{{ item }}</th>
                    {% endfor %}
                </tr>
            </thead>
            <tbody>   {# 表体 #}
                {% for row_list in body_list %}
                <tr>
                    {% for col in row_list %}
                        <td>{{ col }}</td>
                    {% endfor %}
    
                </tr>
                {% endfor %}
            </tbody>
        </table>
    
    </div>
    view
    • 自定义的配置类
    from stark.service.stark import site, StarkConfig
    from app01 import models
    
    site.register(models.UserInfo)
    
    
    class DepartConfig(StarkConfig):
        # 自定义的配置类
        list_display = [StarkConfig.display_checkbox,'id', 'name', 'user']
        #        自定义的显示字段
    
    site.register(models.Depart, DepartConfig)
    view




    编辑删除功能函数实现

    利用函数封装名称标签,组装表每行时 Functiontype判断,取不同值放入row_list
    def display_edit(self, row=None, header=False):
        if header:
            return "编辑"
    
        return mark_safe('<a href="%s"><i class="fa fa-edit" aria-hidden="true"></i></a></a>' % self.reverse_edit_url(row))
    
    def display_del(self, row=None, header=False):
        if header:
            return "删除"
    
        return mark_safe('<a href="%s"><i class="fa fa-trash-o" aria-hidden="true"></i></a>' % self.reverse_del_url(row))
    
    def display_edit_del(self, row=None, header=False):
        if header:
            return "操作"
        tpl = """<a href="%s"><i class="fa fa-edit" aria-hidden="true"></i></a></a> |
        <a href="%s"><i class="fa fa-trash-o" aria-hidden="true"></i></a>
        """ %(self.reverse_edit_url(row),self.reverse_del_url(row),)
        return mark_safe(tpl)
    list display function


    前端循环取组装好的列表里面的值即可
    {% block content %}
        <div>
            {% if add_btn %}
            <div style="margin: 5px 0;">
                {{ add_btn }}
            </div>
            {% endif %}
            <table class="table table-bordered">
                <thead>
                    <tr>
                        {% for item in header_list %}
                        <th>{{ item }}</th>
                        {% endfor %}
                    </tr>
                </thead>
                <tbody>
                    {% for row_list in body_list %}
                    <tr>
                        {% for col in row_list %}
                            <td>{{ col }}</td>
                        {% endfor %}
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    {% endblock %}
    view

    添加数据功能实现

    modeform 实现表单更改验证

    model_form_class = None
    
    
    def get_add_btn(self):
        return mark_safe('<a href="%s" class="btn btn-success">添加</a>' % self.reverse_add_url())
    
    
    
    def get_model_form_class(self):
        """
        获取ModelForm类  # 用于编辑 和 添加数据的表单 
           :return: #根据是否有自定义配置,返回不同表单
        """
        if self.model_form_class:
            return self.model_form_class  #    其他表的配置,如果有自定义的表单则返回自定义的
    
        class AddModelForm(forms.ModelForm):       # 添加功能的表单,所有数据都需要填写,所以默认所有字段都要
            class Meta:
                model = self.model_class
                fields = "__all__"
    
        return AddModelForm
    
    
    
    ModelForm


    def changelist_view(self, request):
        """
        所有URL的查看列表页面 # 将添加按钮功能,添加到这页面视图
        :param request:
        :return:
        """
        queryset = self.model_class.objects.all().order_by(*self.get_order_by())
    
        # ##### 添加按钮 ######
        add_btn = self.get_add_btn()
        ......
    
    
    def add_view(self, request):
        """
        所有添加页面,都在此函数处理
        使用ModelForm实现
        :param request:
        :return:
        """
        AddModelForm = self.get_model_form_class()
        if request.method == "GET":
            form = AddModelForm()
            return render(request, 'stark/change.html', {'form':form})
    
        form = AddModelForm(request.POST) # 校验数据
        if form.is_valid():
            form.save()                 # 保存
            return redirect(self.reverse_list_url())   # 添加完反回主页面
        return render(request, 'stark/change.html', {'form': form})
    
    add_view


    class AdminSite(object):
        def __init__(self):
            self._registry = {}
            self.app_name = 'stark'
            self.namespace = 'stark'
    
        def register(self, model_class, stark_config=None):
            """
            注册表类
            :param model_class: 表类class
            :param stark_config: 自定义配置
            :return:
            """
            if not stark_config:
                stark_config = StarkConfig
    
            self._registry[model_class] = stark_config(model_class, self)  # 实例对象传参
                  """
            {
                models.UserInfo: StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
                models.Role: RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象
            }
            """
    
        def get_urls(self):
            # 获取url
            urlpatterns = []  #url 列表
    
            # urlpatterns.append(url(r'^x3/', ([
            #                                      url(r'^add/', self.x1),
            #                                      url(r'^change/', self.x1),
            #                                      url(r'^del/', self.x1),
            #                                      url(r'^edit/', self.x1),
            #                                  ],None,None)))
    
            for k, v in self._registry.items():
                # k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
                # k=modes.Role,v=RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象
                app_label = k._meta.app_label
                model_name = k._meta.model_name
                urlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))
                #                    表类所在app/表类名的组装                   一个表类绑定的操作url
            return urlpatterns
    
        @property
        def urls(self):
            return self.get_urls(), self.app_name, self.namespace
            #          url列表 
            # 返回的元组
    
    site = AdminSite()
    
    
    AdminSite


    编辑视图函数
    def change_view(self, request, pk):
        """
        所有编辑页面
        :param request:
        :param pk: 操作该条数据的pk,路由有设置
        :return:
        """
        obj = self.model_class.objects.filter(pk=pk).first()
        if not obj:
            return HttpResponse('数据不存在')
    
        ModelFormClass = self.get_model_form_class()
        if request.method == 'GET':
            form = ModelFormClass(instance=obj)    # instance=obj 默认原先的编辑数据
            return render(request,'stark/change.html',{'form':form})
        form = ModelFormClass(data=request.POST,instance=obj)
        if form.is_valid():
            form.save()
            return redirect(self.reverse_list_url())
        return render(request, 'stark/change.html', {'form': form})
    编辑视图处理函数
    {% block content %}
        <div style=" 680px;margin: 0 auto;">
            <form class="change" method="post">
                {% csrf_token %}
                {% for filed in form %}
                    <div class="form-group">
                        <label>{{ filed.label }}</label>
                        {{ filed }}
                        {{ filed.errors.0 }}
                    </div>
                {% endfor %}
    
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
        </div>
    {% endblock %}
    编辑前端页面


    def delete_view(self, request, pk):
        """
        所有删除页面
        :param request:
        :param pk:
        :return:
        """
        if request.method == "GET":
            return render(request,'stark/delete.html',{'cancel_url':self.reverse_list_url()})
        #                   跳转到确认页面                 # 取消反回的url
        self.model_class.objects.filter(pk=pk).delete()   # 不是GET请求,说明确认删除
        return redirect(self.reverse_list_url())
    删除视图处理函数


    {% extends 'stark/layout.html' %}
    {% block css %}
    
    
    {% endblock %}
    {% block content %}
        <div >
            <form method="post">
                {% csrf_token %}
                <p>是否确定要删除?</p>
                <a href="{{ cancel_url }}" class="btn btn-default">取消</a>
                <button type="submit" class="btn btn-danger">确 认</button>
            </form>
        </div>
    {% endblock %}
    
    
    删除确认页面


    def get_urls(self):
        info = self.model_class._meta.app_label, self.model_class._meta.model_name
    
        urlpatterns = [
            url(r'^list/$', self.wrapper(self.changelist_view), name='%s_%s_changelist' % info),
            url(r'^add/$', self.wrapper(self.add_view), name='%s_%s_add' % info),
            url(r'^(?P<pk>d+)/change/', self.wrapper(self.change_view), name='%s_%s_change' % info),
            url(r'^(?P<pk>d+)/del/', self.wrapper(self.delete_view), name='%s_%s_del' % info),
        ]
    
        extra = self.extra_url()
        if extra:
            urlpatterns.extend(extra)
    
        return urlpatterns
    def extra_url(self):
        pass
    
    每张表类绑定的路由

    反向解析,前端提交变更的路由路径

    def reverse_list_url(self):
        app_label = self.model_class._meta.app_label
        model_name = self.model_class._meta.model_name
        namespace = self.site.namespace
        name = '%s:%s_%s_changelist' % (namespace, app_label, model_name)
        list_url = reverse(name)
        return list_url
    
    def reverse_add_url(self):
        app_label = self.model_class._meta.app_label
        model_name = self.model_class._meta.model_name
        namespace = self.site.namespace
        name = '%s:%s_%s_add' % (namespace, app_label, model_name)
        add_url = reverse(name)
        return add_url
    
    def reverse_edit_url(self,row):
        app_label = self.model_class._meta.app_label
        model_name = self.model_class._meta.model_name
        namespace = self.site.namespace
        name = '%s:%s_%s_change' % (namespace, app_label, model_name)
        edit_url = reverse(name, kwargs={'pk': row.pk})
        return edit_url
    
    def reverse_del_url(self,row):
        app_label = self.model_class._meta.app_label
        model_name = self.model_class._meta.model_name
        namespace = self.site.namespace
        name = '%s:%s_%s_del' % (namespace, app_label, model_name)
        del_url = reverse(name, kwargs={'pk': row.pk})
        return del_url
    
    @property
    def urls(self):
        return self.get_urls()
    
    路由解析



    应用配置app01/stark.py
    class DepartModelForm(forms.ModelForm):
        class Meta:
            model = models.Depart
            fields = "__all__"
    
        def clean_name(self):
            return self.cleaned_data['name']
    
    
    class DepartConfig(StarkConfig):   #继承默认配置类
        list_display = [StarkConfig.display_checkbox, 'id', 'name', 'tel', 'user', StarkConfig.display_edit_del]
        model_form_class = DepartModelForm
    
        def changelist_view(self, request):
            return HttpResponse('自定义列表页面')
    
    
    site.register(models.Depart, DepartConfig)
    view








    注册类入口

    class AdminSite(object):
        def __init__(self):
            self._registry = {}
            self.app_name = 'stark'
            self.namespace = 'stark'
    
        def register(self, model_class, stark_config=None):
            """
            注册表类
            :param model_class: 表类class
            :param stark_config: 自定义配置
            :return:
            """
            if not stark_config:
                stark_config = StarkConfig
    
            self._registry[model_class] = stark_config(model_class, self)  # 实例对象传参
                  """
            {
                models.UserInfo: StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
                models.Role: RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象
            }
            """
    
        def get_urls(self):
            # 获取url
            urlpatterns = []  #url 列表
    
            # urlpatterns.append(url(r'^x3/', ([
            #                                      url(r'^add/', self.x1),
            #                                      url(r'^change/', self.x1),
            #                                      url(r'^del/', self.x1),
            #                                      url(r'^edit/', self.x1),
            #                                  ],None,None)))
    
            for k, v in self._registry.items():
                # k=modes.UserInfo,v=StarkConfig(models.UserInfo), # 封装:model_class=UserInfo,site=site对象
                # k=modes.Role,v=RoleConfig(models.Role)           # 封装:model_class=Role,site=site对象
                app_label = k._meta.app_label
                model_name = k._meta.model_name
                urlpatterns.append(url(r'^%s/%s/' % (app_label, model_name,), (v.urls, None, None)))
                #                    表类所在app/表类名的组装                   一个表类绑定的操作url
            return urlpatterns
    
        @property
        def urls(self):
            return self.get_urls(), self.app_name, self.namespace
            #          url列表 
            # 返回的元组
    
    site = AdminSite()
    
    
    
    
    
    class AdminSite


    自定义思路
    a.有自定义配置类的,重写继承的默认类变量,然后再由类方法自己去调用
    b. 在自定义配置类,直接重写继承配置类的默认方法

    1. 排序规则
    
    2. 显示列
       第一种方法:
          class UserInfoConfig(StarkConfig):
             list_display = ['id','title',StarkConfig.display_edit,StarkConfig.display_del]
          site.register(models.UserInfo,UserInfoConfig)
       第二种方法:
          class UserInfoConfig(StarkConfig):
             order_by = ['-id']
    
             def get_list_display(self):
                return  ['id','title',StarkConfig.display_edit,StarkConfig.display_del]
    
    1. 排序规则

    3. 添加按钮
          class UserInfoConfig(StarkConfig):
             list_display = ['id','title',StarkConfig.display_edit,StarkConfig.display_del]
             def get_add_btn(self):
                # 显示 
                # return mark_safe('<a href="%s" class="btn btn-success">添加</a>' % self.reverse_add_url())
    
                # 不显示
                return None
    
          site.register(models.UserInfo,UserInfoConfig)
    3. 添加按钮
    4. 定制ModelForm
       第一种方法:
              class DepartModelForm(forms.ModelForm):
             class Meta:
                model = models.Depart
                fields = "__all__"
    
             def clean_name(self):
                return self.cleaned_data['name']
    
          class DepartConfig(StarkConfig):
             list_display = [StarkConfig.display_checkbox,'id', 'name', 'tel', 'user',StarkConfig.display_edit_del]
             model_form_class = DepartModelForm
       第二种方法:
              class DepartModelForm(forms.ModelForm):
             class Meta:
                model = models.Depart
                fields = "__all__"
    
             def clean_name(self):
                return self.cleaned_data['name']
    
          class DepartConfig(StarkConfig):
             list_display = [StarkConfig.display_checkbox,'id', 'name', 'tel', 'user',StarkConfig.display_edit_del]
    
             def get_model_form_class(self):
    
                return DepartModelForm
    4. 定制ModelForm

    5. 自定义列表页面
       class DepartConfig(StarkConfig):
          list_display = [StarkConfig.display_checkbox,'id', 'name', 'tel', 'user',StarkConfig.display_edit_del]
          model_form_class = DepartModelForm
    
    
          def changelist_view(self, request):
             return HttpResponse('自定义列表页面')
    
    
       site.register(models.Depart, DepartConfig)
    
    6. 增加URL
       class RoleConfig(StarkConfig):
    
          order_by = ['-id', ]
          list_display = [StarkConfig.display_checkbox,'id','title',StarkConfig.display_edit,StarkConfig.display_del]
    
          def extra_url(self):
             data = [
                url(r'^xxxxxxx/$', self.xxxxxx),
             ]
    
             return data
    
          def xxxxxx(self,request):
             print('....')
    
             return HttpResponse('xxxxx')
    
    
       site.register(models.Role,RoleConfig)
    
    7. 自定制URL
    
       class RoleConfig(StarkConfig):
    
          order_by = ['-id', ]
          list_display = [StarkConfig.display_checkbox,'id','title']
    
    
          def get_add_btn(self):
             return False
    
          def extra_url(self):
             data = [
                url(r'^xxxxxxx/$', self.xxxxxx),
             ]
    
             return data
    
          def xxxxxx(self,request):
             print('....')
    
             return HttpResponse('xxxxx')
    
    
          def get_urls(self):
             info = self.model_class._meta.app_label, self.model_class._meta.model_name
    
             urlpatterns = [
                url(r'^list/$', self.wrapper(self.changelist_view), name='%s_%s_changelist' % info),
             ]
    
             extra = self.extra_url()
             if extra:
                urlpatterns.extend(extra)
    
             return urlpatterns
    
       site.register(models.Role,RoleConfig)
    5. 自定义列表页面

  • 相关阅读:
    ASP.NET Web API 2 之文件下载
    Windows 查看某个端口号是否被占用
    C# 数据类型之 String(字符串)
    数据表对应关系(一对一、一对多、多对多)
    嫁给程序员的好处,你get到了吗?
    ASP.NET Web API 2 之 HttpRequestMessage 对象
    C# 使用 log4net 记录日志
    Chrome 浏览器快捷键
    C# 获取程序运行时路径
    SpringBoot整合Pagehelper分页插件
  • 原文地址:https://www.cnblogs.com/wenyule/p/9924784.html
Copyright © 2011-2022 走看看