stark组件开发之添加按钮显示和URL

添加:

  需求: 根据用户的权限, 决定是否,有添加按钮。  通过配置进行定制,预留钩子进行权限的判断。

class StartHandler(object):
    has_add_btn = True  # 指定配置,默认显示。 用户在子类中,自定制是否显示
    def get_add_btn(self):
        ‘‘‘预留钩子,子类中重写该方法。 根据权限的判断是否显示添加按钮‘‘‘
        if self.has_add_btn:
            return "<a class=‘btn btn-primary‘>添加</a>"
        return None
class UserInfoHandler(StartHandler):
    list_display = ["name", "age", "depart", get_choice_txt("性别", "gender"), StartHandler.display_edit,
                    StartHandler.display_del]
    per_page = 1  # 重新定义 每页显示 多少 数据
    has_add_btn = True  # False就表示, 不显示添加按钮

如果感觉,默认的样式不好看!
  可以在, 子类中, 重写get_add_btn() 方法。 返回一个,自己喜欢的样式的 a 标签。 就行了!

然后,就是这个 a 标签的, 路有问题了!  并且还要,携带上,本次请求的  GET 的数据。
老套路: 自定义一个反向解析的,函数:

    def reverse_url(self):
        ‘‘‘用于反向生成url, 并且携带,get请求的参数,跳转到下一个网页‘‘‘
        name = "%s:%s" % (self.site.namespace, self.get_add_url_name)
        base_url = reverse(name)
        # 记录原搜索条件
        if not self.request.GET:
            add_url = base_url
        else:
            param = self.request.GET.urlencode()  # 获取到GET请求的,所有的参数。 ?page=1&age=20
            new_query_dict = QueryDict(mutable=True)
            new_query_dict["_filter"] = param
            add_url = "%s?%s" % (base_url, new_query_dict.urlencode())
        return add_url

这里最重要的一个就是, self.request  这个东西, 是从前端传过来的, 我在初始化函数里面,定义了一下。 但是 他从哪里传给我的初始化函数呢?  就是在,获取 URL 的时候。

    def wrapper(self, func):
        @functools.wraps(func)  # 保留原函数的 原信息
        def inner(request, *args, **kwargs):  # 这个inner 就是,我的每一个视图函数了!
            self.request = request
            return func(request, *args, **kwargs)
        return inner

    def get_urls(self):
        partterns = [
            re_path(r"list/$", self.wrapper(self.check_list_view), name=self.get_list_url_name),
            re_path(r"add/$", self.wrapper(self.add_view), name=self.get_add_url_name),
            re_path(r"change/(\d+)/$", self.wrapper(self.change_view), name=self.get_edit_url_name),
            re_path(r"del/(\d+)/$", self.wrapper(self.delete_view), name=self.get_del_url_name),
        ]

为了避免麻烦, 使用了 闭包的方式。来做这件事!
解释一下:


    def wrapper(self, func):
        @functools.wraps(func)  # 保留原函数的 原信息
        def inner(request, *args, **kwargs):  # 这个inner 就是,我的每一个视图函数了!
            self.request = request
            return func(request, *args, **kwargs)
        return inner
self.wrapper(self.check_list_view)
这里做的工作其实就是:
self.check_list_view = self.wrapper(self.check_list_view)  # self.check_list_view == inner 可以这么理解
self.wrapper的返回值是  inner 函数的内存地址。所以其实执行  self.check_list_view  就相当于执行的是 inner。re_path()  这个django内部的函数。 认为  self.wrapper(self.check_list_view)  是一个视图函数。 所以会给他带上一个  request 的参数。

注:self.wrapper(self.check_list_view) 这个一位加了 括号, 所以会先执行。并返回 inner。 而re_path 认为inner 就是视图函数。

所以我才能够在 inner 这个函数这里, 直接收到这个 request 。 然后我就将他 赋值给了, __init__ 初始化函数中的。 self.request = None

这样这参数,就不再是 None  而是一个,带着从前端返回的,带有参数的 request 对象。
我就可以,在程序的, 其他地方。 使用这个参数。

整体结构,就是这样:

    def get_add_btn(self):
        ‘‘‘预留钩子,子类中重写该方法。 根据权限的判断是否显示添加按钮‘‘‘
        if self.has_add_btn:
            # 根据别名反向生成, URL
            add_url = self.reverse_url()
            return "<a class=‘btn btn-primary‘ href=‘%s‘>添加</a>" % add_url
        return None

    def reverse_url(self):
        ‘‘‘用于反向生成url, 并且携带,get请求的参数,跳转到下一个网页‘‘‘
        name = "%s:%s" % (self.site.namespace, self.get_add_url_name)
        base_url = reverse(name)
        # 记录原搜索条件
        if not self.request.GET:
            add_url = base_url
        else:
            param = self.request.GET.urlencode()  # 获取到GET请求的,所有的参数。 ?page=1&age=20
            new_query_dict = QueryDict(mutable=True)
            new_query_dict["_filter"] = param
            add_url = "%s?%s" % (base_url, new_query_dict.urlencode())
        return add_url

    per_page = 10  # 默认每页显示,多少数据。 也可在子类中,自行定制

    def check_list_view(self, request):
        ‘‘‘
        列表查看页面
        :param request:
        :return:
        ‘‘‘
        # self.request = request  # 进入查看页面,为request赋值! 使其他地方可以用到!
        list_display = self.get_list_display()
        # 页面要显示的列 self.list_display  示例:[‘name‘, ‘age‘, ‘depart‘]

        # 1. 制作表头, 就是每张表中,每个字段写的 verbose_name.。 如何获取到这个值呢?
        # self.model_class._meta.get_field(‘name‘).verbose_name
        header_list = []  # 表头
        if list_display:
            for key_or_func in list_display:
                if isinstance(key_or_func, FunctionType):  # 判断当前参数, 是一个字符串还是一个函数。
                    verbose_name = key_or_func(self, obj=None, is_header=True)
                else:
                    verbose_name = self.model_class._meta.get_field(key_or_func).verbose_name
                header_list.append(verbose_name)
        else:
            header_list.append(self.model_class._meta.model_name)

        # 2. 处理 从数据库 取到的数据   # 用户访问的表  self.model_class
        #   2.1 ###############处理分页#################
        ‘‘‘1.根据用户访问页面,计算出索引的位置, 比如 page=3
            2. 生成html页码
        ‘‘‘
        all_count = self.model_class.objects.all().count()
        query_params = request.GET.copy()  # page=1&level=2
        query_params._mutable = True  # request.get中的值默认是不能被修改的。加上这句代码就可以修改了

        pager = Pagination(
            current_page=request.GET.get("page"),  # 用户访问的当前叶
            all_count=all_count,  # 数据库一共有多少数据
            base_url=request.path_info,  # 所在的url 就是 ?page=1 之前的URL
            # 用于保留,用户的请求信息,比如 level=2 被用户先选中。 那么分页后。因为查询的东西少了,分页也应该想要的减少,
            # 但是level=2这个, 请求的信息!不能因为。分页的原因。而减少。
            query_params=query_params,
            per_page=self.per_page,  # 每页显示多少数据。
        )

        #  2.1  ###############处理表格#################
        data_list = self.model_class.objects.all()[pager.start:pager.end]

        body_list = []
        for row in data_list:
            row_list = []
            if list_display:
                for key_or_func in list_display:
                    if isinstance(key_or_func, FunctionType):
                        # 这里is_header=False  obj=row(数据库中循环的每一行的对象)
                        row_list.append(key_or_func(self, obj=row, is_header=False))
                    else:
                        row_list.append(getattr(row, key_or_func))
            else:
                row_list.append(row)
            body_list.append(row_list)
        # 3 ############# 处理添加按钮####################
        add_btn = self.get_add_btn()  # 在这里调用了!此方法!

        return render(request, "stark/changelist.html",
                      {"header_list": header_list, "data_list": data_list,
                       "body_list": body_list,
                       "pager": pager,
                       "add_btn": add_btn})

原文地址:https://www.cnblogs.com/chengege/p/10739723.html

时间: 2024-08-30 00:34:49

stark组件开发之添加按钮显示和URL的相关文章

stark组件开发之编辑功能实现

编辑功能.和添加一样! 唯一不同的就是, 需要编辑一个指定的  记录.这就需要,在列表页面, 渲染编辑的时候,添加一个 id 值: def memory_url(self, get_url_name, *args, **kwargs): '''用于反向生成url, 并且携带,get请求的参数,跳转到下一个网页''' name = "%s:%s" % (self.site.namespace, get_url_name) base_url = reverse(name, args=arg

stark组件开发之组合搜索页面效果和 URL

页面效果,只是样式.这个好解决!yield 的时候. 返回几个样式出去就好了! 并且前端写上一些样式的css {% if search_group_row_list %} <div class="panel panel-default"> <div class="panel-heading"> <i class="fa fa-filter" aria-hidden="true"></i

stark组件开发之提取公共视图函数

 路由问题, 已经解决! 然后就是视图函数的问题了: 不想重复写的解决途径就是, python  类的继承了! 写一个基类, 基类定义 增删改查. 然后其他的,全部去继承他! from django.urls import path, re_path from django.http import HttpResponse, JsonResponse from django.shortcuts import render, redirect, reverse from app01 import

Django——stark组件

stark组件是仿照django的admin模块开发的一套组件,它的作用是在网页上对注册的数据表进行增删改查操作. 一.配置 1.创建stark应用,在settings.py中注册stark应用 stark APP专门用于存放自定义组件的核心代码. manage.py@stark_demo > startapp stark 在settings.py文件注册stark: INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth'

stark组件配置,二层URL

1.django的admin配置 2 stark组件开发 3.2层url分发 4.小结 1.django的admin配置 model.py from django.db import models # Create your models here. class UserInfo(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.

iOS开发UI篇—在ImageView中添加按钮以及Tag的参数说明

一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwithtag: 提示点:在xib中如果想要通过tag参数获取对应的控件(属性),不要把tag的参数设置为0,因为xib中所有的对象默认tag都为0,设置为0取不到对象. 二.ImageView中添加按钮 (1)ImageView和Button的比较 Button按钮的内部可以放置多张图片(4),而ImageView中只能放置一张图片. (2)说明: ImageView只

文顶顶 iOS开发UI篇—在UIImageView中添加按钮以及Tag的参数说明

ios开发UI篇—在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwithtag: 提示点:在xib中如果想要通过tag参数获取对应的控件(属性),不要把tag的参数设置为0,因为xib中所有的对象默认tag都为0,设置为0取不到对象. 二.ImageView中添加按钮(1)ImageView和Button的比较 Button按钮的内部可以放置多张图片(4),而Ima

Quick-Cocos2d-x初学者游戏教程(四) --------------- 开发初探(添加背景,标题,动作,按钮)

Quick-Cocos2d-x初学者游戏教程(四) 前面我们已经大概的讲解完了Quick的框架和代码结构,接下来,本章开始我们将正式进入到游戏的开发.当然在开发的过程中,如果遇到值得一提的知识点和概念,我们还是会为大家详细讲解的. 哈哈,这章的内容我加它为——开发初探,因为我们将先来实现一些基础的内容.本章将实现的效果如下图所示: 菜单场景 从前面章节讲解的的知识点中,我们知道每个新建的 Quick 项目里都已经默认创建好了一个 mainScene 场景,所以下面我们将利用这个现成的场景,把它改

IOS开发UI基础—在UIImageView中添加按钮以及Tag的参数说明

ios开发UI基础-在ImageView中添加按钮以及Tag的参数说明 一.tag参数 一个视图通常都只有一个父视图,多个子视图,在开发中可以通过使用子视图的tag来取出对应的子视图.方法为Viewwithtag: 提示点:在xib中如果想要通过tag参数获取对应的控件(属性),不要把tag的参数设置为0,因为xib中所有的对象默认tag都为0,设置为0取不到对象. 二.ImageView中添加按钮(1)ImageView和Button的比较 Button按钮的内部可以放置多张图片(4),而Im