stark組件開發之添加按鈕顯示和URL

添加:html

  需求: 根據用戶的權限, 決定是否,有添加按鈕。  經過配置進行定製,預留鉤子進行權限的判斷。前端

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

  def check_list_view(self, request, *args, **kwargs):
    # ################6. 處理添加按鈕######################
    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,
               "search_list": search_list,
               "search_value": search_value,
               "action_dict": action_dict})

  ..................

 

 

class UserInfoHandler(StartHandler):
    list_display = ["name", "age", "depart", get_choice_txt("性別", "gender"), StartHandler.display_edit,
                    StartHandler.display_del]
    has_add_btn = True  # False就表示, 不顯示添加按鈕

      get_add_btn(self):  #  能夠進行重寫。 權限的判斷,或者,重寫樣式python

      pass數據庫

若是感受,默認的樣式很差看!
  能夠在, 子類中, 重寫get_add_btn() 方法。 返回一個,本身喜歡的樣式的 a 標籤。 就好了!django

而後,就是這個 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 的時候。app

    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 就是視圖函數。url

因此我纔可以在 inner 這個函數這裏, 直接收到這個 request 。 而後我就將他 賦值給了, __init__ 初始化函數中的。 self.request = Nonespa

這樣這參數,就再也不是 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})
相關文章
相關標籤/搜索