stark組件開發之添加按鈕顯示和URL
阿新 • • 發佈:2019-04-20
pri 添加按鈕 訪問 delete obj ttr 就是 () 表頭 可以在, 子類中, 重寫get_add_btn() 方法。 返回一個,自己喜歡的樣式的 a 標簽。 就行了!
添加:
需求: 根據用戶的權限, 決定是否,有添加按鈕。 通過配置進行定制,預留鉤子進行權限的判斷。
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就表示, 不顯示添加按鈕
如果感覺,默認的樣式不好看!
然後,就是這個 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})
stark組件開發之添加按鈕顯示和URL