app01/stark.py:css
class BookConfig(ModelStark): list_display = ["title", "price", "publishDate"] modelform_class = BookModelForm search_fields = ['title', "price"] def patch_init(self, request, queryset): print(queryset) queryset.update(price=123) patch_init.short_description = "批量初始化" actions = [patch_init] list_filter = ["publish", "authors", ] # 一對多、多對多 site.register(Book, BookConfig)
class ShowList(object): """展現頁面類""" def __init__(self, config, data_list, request):... def get_filter_linktags(self): """獲取過濾字段""" link_list = {} print("list_filter", self.config.list_filter) # list_filter ['publish', 'authors'] for filter_field in self.config.list_filter: print(filter_field) # 'publish' 'authors' # 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) print(filter_field_obj) # app01.Book.publish app01.Book.authors print(type(filter_field_obj)) """ <class 'django.db.models.fields.related.ForeignKey'> <class 'django.db.models.fields.related.ManyToManyField'> from django.db.models.fields.related import ForeignKey from django.db.models.fields.related import ManyToManyField """ # 拿到關聯表下的全部數據 # print("rel...", filter_field_obj.rel.to.objects.all()) # 版本問題失效 print("rel...", filter_field_obj.related_model.objects.all()) """ rel... <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> rel... <QuerySet [<Author: alex>, <Author: egon>]> """ return link_list class ModelStark(object): """默認類,定製配置類""" list_display = ["__str__",] list_display_links = [] modelform_class = [] search_fields = [] actions = [] # 調用self.actions拿到的是函數 list_filter = []
注意:html
ShowList類對象,經過self.config.list_filter能夠拿到當前訪問頁面對象自定義配置類配置的list_filter列表。java
filter_field_obj = self.config.model._meta.get_field(filter_field) model_name = self.config.model._meta.model_name # 模型名 book app_label = self.config.model._meta.app_label # app名 app01
# 拿到關聯表下的全部數據 # print("rel...", filter_field_obj.rel.to.objects.all()) # 版本問題失效(filter_field_obj.rel.to是關聯模型表) print("rel...", filter_field_obj.related_model.objects.all()) # 拿到對象下的關聯數據 """ rel... <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> rel... <QuerySet [<Author: alex>, <Author: egon>]> """
class ShowList(object): """展現頁面類""" def get_filter_linktags(self): """獲取過濾字段""" link_dic = {} print("list_filter", self.config.list_filter) # list_filter ['publish', 'authors'] for filter_field in self.config.list_filter: print(filter_field) # 'publish' 'authors' # 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) print(filter_field_obj) # app01.Book.publish app01.Book.authors # 拿到關聯表下的全部數據 # print("rel...", filter_field_obj.rel.to.objects.all()) # 版本問題失效 # print("rel...", filter_field_obj.related_model.objects.all()) # <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> data_list = filter_field_obj.related_model.objects.all() # <QuerySet [<Publish: 蘋果出版社> temp = [] for obj in data_list: # obj是每個對象 # print(obj) # 蘋果出版社 香蕉出版社 alex egon # print(type(obj)) # <class 'app01.models.Publish'> <class 'app01.models.Author'> link_tag = "<a href=>%s</a>" % str(obj) # print(link_tag) # <a href=>蘋果出版社</a> temp.append(link_tag) link_dic[filter_field] = temp # print(link_dic) # {'publish': ['<a href=>蘋果出版社</a>', '<a href=>香蕉出版社</a>'], 'authors': ['<a href=>alex</a>', '<a href=>egon</a>']} return link_dic
這裏最重要就是理清楚每一個變量的類型和含義:python
self.config.list_filter——['publish', 'authors'] filter_field_obj—— app01.Book.publish、app01.Book.authors filter_field_obj.related_model.objects.all()——<QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]>、<QuerySet [<Author: alex>, <Author: egon>]> obj——蘋果出版社 香蕉出版社 alex egon 數據類型:<class 'app01.models.Publish'> <class 'app01.models.Author'> link_tag——<a href=>蘋果出版社</a> link_dic——{'publish': ['<a href=>蘋果出版社</a>', '<a href=>香蕉出版社</a>'], 'authors': ['<a href=>alex</a>', '<a href=>egon</a>']}
<h4>數據列表</h4> <div class="container"> <div class="row"> <div class="col-md-9".....> <div class="col-md-3"> <div class="filter"> <h4>Filter</h4> {% for filter_field, linktags in show_list.get_filter_linktags.items %} <div> <p>{{ filter_field }}</p> {% for link in linktags %} <p>{{ link|safe }}</p> {% endfor %} </div> {% endfor %} </div> </div> </div> </div>
注意這裏使用{{link|safe}}來實現取消轉義。顯示效果以下:django
class ShowList(object): """展現頁面類""" def get_filter_linktags(self): """獲取過濾字段""" link_dic = {} print("list_filter", self.config.list_filter) # list_filter ['publish', 'authors'] for filter_field in self.config.list_filter: """循環每個過濾字段""" import copy # self.request.GET # GET請求的全部數據 params = copy.deepcopy(self.request.GET) print(filter_field) # 'publish' 'authors' # 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) print(filter_field_obj) # app01.Book.publish app01.Book.authors # 拿到關聯表下的全部數據 # print("rel...", filter_field_obj.rel.to.objects.all()) # 版本問題失效 # print("rel...", filter_field_obj.related_model.objects.all()) # <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> data_list = filter_field_obj.related_model.objects.all() # <QuerySet [<Publish: 蘋果出版社> temp = [] for obj in data_list: # obj是每個對象 """循環每個過濾字段關聯的數據""" # 構成一個新字典 過濾字段:當前對象主鍵值 params[filter_field + "__id"] = obj.pk # 利用urlencode將鍵值對轉化爲a=1&b=2的格式 _url = params.urlencode() # print(obj) # 蘋果出版社 香蕉出版社 alex egon # print(type(obj)) # <class 'app01.models.Publish'> <class 'app01.models.Author'> link_tag = "<a href='?%s'>%s</a>" % (_url, str(obj)) # print(link_tag) # <a href=>蘋果出版社</a> temp.append(link_tag) link_dic[filter_field] = temp # print(link_dic) # {'publish': ['<a href=>蘋果出版社</a>', '<a href=>香蕉出版社</a>'], 'authors': ['<a href=>alex</a>', '<a href=>egon</a>']} return link_dic
注意:數組
直接賦值:其實就是對象的引用(別名)。app
淺拷貝(copy):拷貝父對象,不會拷貝對象的內部的子對象。函數
深拷貝(deepcopy): copy 模塊的 deepcopy 方法,徹底拷貝了父對象及其子對象。url
這裏每循環一次過濾字段都會從新建立一個params。保證按鈕對應路徑的惟一性。spa
這裏主要是應爲發送的是get請求,請求數據必須是a=1&b=2的格式。
self.request.GET獲取的是GET請求的全部數據,屢次點擊能夠實現get請求數據的拼接。打印params,在頁面點擊訪問,控制檯輸出以下:
params <QueryDict: {}> ——沒有點擊a標籤 params <QueryDict: {'authors__id': ['1']}> ——第一次點擊 params <QueryDict: {'authors__id': ['1'], 'publish__id': ['2']}> ——第二次點擊
(1)將過濾字段顯示爲大寫
{% for filter_field, linktags in show_list.get_filter_linktags.items %} <div class="well"> {# upper方法改成大寫 #} <p>{{ filter_field.upper }}</p> {% for link in linktags %} <p>{{ link|safe }}</p> {% endfor %} </div> {% endfor %}
(2)取消a標籤顏色
<style> .filter a { text-decoration: none; /* 取消a標籤顏色 */ color: grey; } </style>
class ShowList(object): def get_filter_linktags(self): """獲取過濾字段""" link_dic = {} print("list_filter", self.config.list_filter) # list_filter ['publish', 'authors'] for filter_field in self.config.list_filter: """循環每個過濾字段""" import copy # self.request.GET # GET請求的全部數據 params = copy.deepcopy(self.request.GET) print("params", params) # cid是當前字段傳過來的值 cid = self.request.GET.get(filter_field + "__id", 0) # 沒有值的時候默認爲None,None是不能進行int()轉換的,所以在這裏給它設置默認值爲0 # print(filter_field) # 'publish' 'authors' # 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) data_list = filter_field_obj.related_model.objects.all() # <QuerySet [<Publish: 蘋果出版社> temp = [] for obj in data_list: # obj是每個對象 """循環每個過濾字段關聯的數據""" # 構成一個新字典 過濾字段:當前對象主鍵值 params[filter_field + "__id"] = obj.pk # 利用urlencode將鍵值對轉化爲a=1&b=2的格式 _url = params.urlencode() if int(cid) == obj.pk: # get請求數據int轉換後與對象主鍵值匹配,匹配成功添加active類 link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, str(obj)) else: link_tag = "<a href='?%s'>%s</a>" % (_url, str(obj)) temp.append(link_tag) link_dic[filter_field] = temp return link_dic
給模板添加樣式:
<style> .filter a { text-decoration: none; /* 取消a標籤顏色 */ color: grey; } .active { color: red!important; /* 提高優先級 */ } </style>
注意:
cid = self.request.GET.get(filter_field + "__id", 0)
須要注意的是在get請求沒有值的時候,默認值是None,可是None是不能進行int()轉換的,所以在這裏給它設置默認值0.
if int(cid) == obj.pk: # get請求數據int轉換後與對象主鍵值匹配,匹配成功添加active類 link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, str(obj)) else: link_tag = "<a href='?%s'>%s</a>" % (_url, str(obj))
class ShowList(object): def get_filter_linktags(self): """獲取過濾字段""" link_dic = {} print("list_filter", self.config.list_filter) # list_filter ['publish', 'authors'] for filter_field in self.config.list_filter: """循環每個過濾字段""" import copy # self.request.GET # GET請求的全部數據 params = copy.deepcopy(self.request.GET) print("params", params) # <QueryDict: {'publish__id': ['1']}> # cid是當前字段傳過來的值 cid = self.request.GET.get(filter_field + "__id", 0) # 沒有值的時候默認爲None,None是不能進行int()轉換的,所以在這裏給它設置默認值爲0 # 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) data_list = filter_field_obj.related_model.objects.all() # <QuerySet [<Publish: 蘋果出版社> temp = [] # 處理all標籤 if params.get(filter_field + "__id"): del params[filter_field + "__id"] temp.append("<a href='?%s'>all</a>" % params.urlencode()) else: temp.append("<a class='active' href='#'>all</a>") # 默認是all的狀態 # 處理數據標籤 for obj in data_list: # obj是每個對象 """循環每個過濾字段關聯的數據""" # 構成一個新字典 過濾字段:當前對象主鍵值 params[filter_field + "__id"] = obj.pk # 利用urlencode將鍵值對轉化爲a=1&b=2的格式 _url = params.urlencode() if int(cid) == obj.pk: # get請求數據int轉換後與對象主鍵值匹配,匹配成功添加active類 link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, str(obj)) else: link_tag = "<a href='?%s'>%s</a>" % (_url, str(obj)) temp.append(link_tag) link_dic[filter_field] = temp return link_dic
注意:
# 處理all標籤 if params.get(filter_field + "__id"): del params[filter_field + "__id"] temp.append("<a href='?%s'>all</a>" % params.urlencode()) else: temp.append("<a class='active' href='#'>all</a>") # 默認是all的狀態
點擊a標籤因爲href沒有在?前填任何值,默認是將get請求發送給原函數處理。
params是深度複製了get請求的數據,所以每次點擊a標籤都在添加params的值:
params <QueryDict: {}> ——沒有點擊a標籤 params <QueryDict: {'authors__id': ['1']}> ——第一次點擊 params <QueryDict: {'authors__id': ['1'], 'publish__id': ['2']}> ——第二次點擊
params.get(filter_field + "__id") 就能夠拿到對應的authors__id和publish__id.若是if判斷拿不到值,說明尚未進行過濾,添加帶有active類的a標籤:<a class='active' href='#'>all</a>。all標籤顯示爲激活狀態。
若是if判斷有值,經過del方法清除對應的params中的值,添加不帶有active類的a標籤:
temp.append("<a href='?%s'>all</a>" % params.urlencode())
# 訪問http://127.0.0.1:8000/stark/app01/book/?authors__id=1&publish__id=1 print("urlencode", params.urlencode) print("_url", params.urlencode()) print("params", params) """ urlencode <bound method QueryDict.urlencode of <QueryDict: {'authors__id': ['1'], 'publish__id': ['1']}>> _url authors__id=1&publish__id=1 params <QueryDict: {'authors__id': ['1'], 'publish__id': ['1']}> """
經過點擊按鈕修改href值,修改每次發送的get請求數據。
此時查看PUBLISH下的all按鈕:
此時查看PUBLISH下的香蕉出版社:
class ShowList(object): """展現頁面類""" def __init__(self, config, data_list, request): self.config = config # 接收傳遞過來的配置類對象 ModelStark的實例對象 self.data_list = data_list # 接收傳遞過來的當前表的全部對象 self.request = request # <WSGIRequest: GET '/stark/app01/book/?page=2'> # 分頁 data_count = self.data_list.count() current_page = int(self.request.GET.get("page", 1)) # 默認是第一頁 base_path = self.request.path # /stark/app01/book/ self.pagination = Pagination(current_page, data_count, base_path, self.request.GET, per_page_num=3, pager_count=11,) # print("data_list", self.data_list) # data_list <QuerySet [<Book: python葵花寶典>, <Book: go>, <Book: java>]> self.page_data = self.data_list[self.pagination.start:self.pagination.end] # print("page_data", self.page_data) # page_data <QuerySet [<Book: python葵花寶典>]> # actions # self.actions = self.config.actions # 拿到配置好的函數對象列表 [patch_init,] self.actions = self.config.new_actions() # 拿到方法運行的返回結果 def get_filter_linktags(self): """獲取過濾字段""" link_dic = {} print("list_filter", self.config.list_filter) # list_filter ['publish', 'authors'] for filter_field in self.config.list_filter: """循環每個過濾字段""" import copy # self.request.GET # GET請求的全部數據 params = copy.deepcopy(self.request.GET) print("params", params) # <QueryDict: {'publish__id': ['1']}> # cid是當前字段傳過來的值 cid = self.request.GET.get(filter_field, 0) # 沒有值的時候默認爲None,None是不能進行int()轉換的,所以在這裏給它設置默認值爲0 # print(filter_field) # 'publish' 'authors' # 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) # print(filter_field_obj) # app01.Book.publish app01.Book.authors # 拿到關聯表下的全部數據 # print("rel...", filter_field_obj.rel.to.objects.all()) # 版本問題失效 # print("rel...", filter_field_obj.related_model.objects.all()) # <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> data_list = filter_field_obj.related_model.objects.all() # <QuerySet [<Publish: 蘋果出版社> temp = [] # 處理all標籤 if params.get(filter_field): print("_url", params.urlencode) del params[filter_field] temp.append("<a href='?%s'>all</a>" % params.urlencode()) else: temp.append("<a class='active' href='#'>all</a>") # 默認是all的狀態 # 處理數據標籤 for obj in data_list: # obj是每個對象 """循環每個過濾字段關聯的數據""" # 構成一個新字典 過濾字段:當前對象主鍵值 params[filter_field] = obj.pk # 利用urlencode將鍵值對轉化爲a=1&b=2的格式 _url = params.urlencode() if int(cid) == obj.pk: # get請求數據int轉換後與對象主鍵值匹配,匹配成功添加active類 link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, str(obj)) else: # print(obj) # 蘋果出版社 香蕉出版社 alex egon # print(type(obj)) # <class 'app01.models.Publish'> <class 'app01.models.Author'> link_tag = "<a href='?%s'>%s</a>" % (_url, str(obj)) # print(link_tag) # <a href=>蘋果出版社</a> temp.append(link_tag) link_dic[filter_field] = temp # print(link_dic) # {'publish': ['<a href=>蘋果出版社</a>', '<a href=>香蕉出版社</a>'], 'authors': ['<a href=>alex</a>', '<a href=>egon</a>']} return link_dic
class ModelStark(object): def get_filter_condition(self, request): """拿到過濾條件""" filter_condition = Q() # 默認查詢條件爲且 and for filter_field, val in request.GET.items(): # 過濾字段、查詢的值 去除fitler_field拼接的__id if filter_field in self.list_filter: # 只處理filter過濾列表的鍵值(分頁等排除) filter_condition.children.append((filter_field, val)) return filter_condition
注意get_filter_condition只處理filter過濾列表鍵值,須要將分頁等請求數據排除。
class ModelStark(object): def list_view(self, request): if request.method == "POST": # action print("POST:", request.POST) action = request.POST.get("action") selected_pk = request.POST.getlist("selected_pk") # 拿到列表 # 反射 # self這裏是配置類BookConfig,要在類中找到對應的函數 action_func = getattr(self, action) # patch_init # 拿到選中狀態的pk值對象 queryset = self.model.objects.filter(pk__in=selected_pk) # <QuerySet [<Book: go>]> action_func(request, queryset) # 獲取search的Q對象 search_condition = self.get_search_condition(request) # 獲取filter構建Q對象 filter_condition = self.get_filter_condition(request) # 篩選當前表獲取的數據 data_list = self.model.objects.all().filter(search_condition).filter(filter_condition) # 鏈式操做,二次過濾 # 獲取showlist展現頁面 show_list = ShowList(self, data_list, request) header_list = show_list.get_header() new_data_list = show_list.get_body() # 構建一個查看url add_url = self.get_add_url() print("add_url", add_url) return render(request, "list_view.html", locals())
注意這裏是運用了鏈式操做,二次過濾。過濾效果顯示以下:
app01/stark.py:
class BookConfig(ModelStark): list_display = ["title", "price", "publishDate", "publish", "authors"] list_display_links = ["title"] modelform_class = BookModelForm search_fields = ['title', "price"] def patch_init(self, request, queryset): print(queryset) queryset.update(price=123) patch_init.short_description = "批量初始化" actions = [patch_init] list_filter = ["publish", "authors", ] # 一對多、多對多 site.register(Book, BookConfig)
publish是一對多字段、authors是多對多字段。頁面顯示以下:
能夠看到多對多字段沒法正常顯示,這個由於在service/stark.py中
class ShowList(object): """展現頁面類""" def get_body(self): """構建表單數據""" new_data_list = [] # for obj in self.data_list: for obj in self.page_data: # 當前頁面的數據 temp = [] for field in self.config.new_list_display(): # ["__str__", ] ["pk","name","age",edit] if callable(field): val = field(self.config, obj) else: val = getattr(obj, field) # 拿到的關聯對象 處理不了多對多 if field in self.config.list_display_links: # _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) _url = self.config.get_change_url(obj) val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp) return new_data_list
get_body方法,val = getattr(obj, field)拿到的是關聯對象,在一對1、一對多狀況下,利用模型定了__str__能夠正常顯示名稱,可是卻沒法處理多對多的狀況。
class ShowList(object): """展現頁面類""" def get_body(self): """構建表單數據""" new_data_list = [] # for obj in self.data_list: for obj in self.page_data: # 當前頁面的數據 temp = [] for field in self.config.new_list_display(): # ["__str__", ] ["pk","name","age",edit] if callable(field): val = field(self.config, obj) else: from django.db.models.fields.related import ManyToManyField field_obj = self.config.model._meta.get_field(field) # 拿到字段對象 if isinstance(field_obj, ManyToManyField): # 判斷是不是多對多 # 反射處理 增長.all # 多對多的狀況 obj.field.all() ret = getattr(obj, field).all() # <QuerySet [<Author: alex>, <Author: egon>]> t = [] for obj in ret: t.append(str(obj)) val = ",".join(t) # 用join方法實現拼接 alex,egon else: # 非多對多的狀況 val = getattr(obj, field) # 拿到的關聯對象 處理不了多對多 if field in self.config.list_display_links: # _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) _url = self.config.get_change_url(obj) val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp) return new_data_list
顯示效果:
注意:
from django.db.models.fields.related import ManyToManyField field_obj = self.config.model._meta.get_field(field) # 拿到字段對象 if isinstance(field_obj, ManyToManyField): # 判斷是不是多對多
# 反射處理 增長.all # 多對多的狀況 obj.field.all() ret = getattr(obj, field).all() # <QuerySet [<Author: alex>, <Author: egon>]> t = [] for obj in ret: t.append(str(obj)) val = ",".join(t) # 用join方法實現拼接 alex,egon
print("ret",getattr(obj, field)) # ret app01.Author.None print("ret", getattr(obj, field).all()) # ret <QuerySet [<Author: alex>, <Author: egon>]>
用於將序列中的元素以指定的字符鏈接生成一個新的字符串。
str = "-" seq = ("a", "b", "c") # 字符串序列 print str.join( seq ) # a-b-c
app01/stark.py:
class BookConfig(ModelStark): list_display = ["title", "price", "publishDate", "publish", "authors"] list_display_links = ["title"] modelform_class = BookModelForm search_fields = ['title', "price"] def patch_init(self, request, queryset): print(queryset) queryset.update(price=123) patch_init.short_description = "批量初始化" actions = [patch_init] list_filter = ["title", "publish", "authors", ] # 普通字段、一對多、多對多 site.register(Book, BookConfig)
添加後訪問頁面直接報錯:
這是因爲在ShowList類get_filter_linktags方法中:
# 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) # 關聯表下全部數據 data_list = filter_field_obj.related_model.objects.all() # <QuerySet [<Publish: 蘋果出版社>
data_list這種取法只適用於一對一和一對多的狀況。
from django.db.models.fields.related import ManyToManyField, ForeignKey class ShowList(object): """展現頁面類""" def get_filter_linktags(self): """獲取過濾字段""" link_dic = {} print("list_filter", self.config.list_filter) # list_filter ['publish', 'authors'] for filter_field in self.config.list_filter: """循環每個過濾字段""" import copy params = copy.deepcopy(self.request.GET) cid = self.request.GET.get(filter_field, 0) # 獲取字段對象 filter_field_obj = self.config.model._meta.get_field(filter_field) if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField): data_list = filter_field_obj.related_model.objects.all() # <QuerySet [<Publish: 蘋果出版社> else: # 普通字段直接查詢 data_list = self.config.model.objects.all().values("pk", filter_field) # 主鍵值 字段對象值
引入ForeignKey和ManyToManyField類,利用isinstance判斷是不是一對多、多對多對象。若是不是就是普通字段,直接查詢處理。
# 處理數據標籤 for obj in data_list: # obj是每個對象 """循環每個過濾字段關聯的數據""" if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField): # <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> pk = obj.pk text = str(obj) else: # 列表裏面套着字典 data_list=[{"pk":1, "title":"go"},....] pk = obj.get("pk") text = obj.get(filter_field) # 構成一個新字典 過濾字段:當前對象主鍵值 params[filter_field] = pk # 利用urlencode將鍵值對轉化爲a=1&b=2的格式 _url = params.urlencode() if int(cid) == pk: # get請求數據int轉換後與對象主鍵值匹配,匹配成功添加active類 link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, text) else: # print(obj) # 蘋果出版社 香蕉出版社 alex egon # print(type(obj)) # <class 'app01.models.Publish'> <class 'app01.models.Author'> link_tag = "<a href='?%s'>%s</a>" % (_url, text)
兩種data_list,一種是QuerySet,一種是數組套字典。兩種數據類型的處理方式略有不一樣。
顯示效果:
這樣作完後點擊TITLE下的過濾項是查不到任何對應數據的。這是由於默認傳遞的過濾字段都是PK值,可是針對普通字段過濾須要傳遞過濾字段值。
# 處理數據標籤 for obj in data_list: # obj是每個對象(或者是數組) """循環每個過濾字段關聯的數據""" if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField): # <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> pk = obj.pk text = str(obj) params[filter_field] = pk # 過濾字段:當前對象主鍵值 else: # 列表裏面套着字典 data_list=[{"pk":1, "title":"go"},....] pk = obj.get("pk") text = obj.get(filter_field) params[filter_field] = text # 過濾字段:當前對象字段值 # 利用urlencode將鍵值對轉化爲a=1&b=2的格式 _url = params.urlencode() if cid == str(pk) or cid == text: # get請求數據int轉換後與對象主鍵值匹配,匹配成功添加active類 link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, text) else: # print(obj) # 蘋果出版社 香蕉出版社 alex egon # print(type(obj)) # <class 'app01.models.Publish'> <class 'app01.models.Author'> link_tag = "<a href='?%s'>%s</a>" % (_url, text) # print(link_tag) # <a href=>蘋果出版社</a> temp.append(link_tag)
注意:
一開始統一用params[filter_field] = pk 來設置過濾字段,可是設置普經過濾字段後,若是title=7這樣是沒法進行過濾的,必須讓過濾字段等於"go"、"python"等字段值。所以將params也分拆爲兩種狀況:
if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField): # <QuerySet [<Publish: 蘋果出版社>, <Publish: 香蕉出版社>]> pk = obj.pk text = str(obj) params[filter_field] = pk # 過濾字段:當前對象主鍵值 else: # 列表裏面套着字典 data_list=[{"pk":1, "title":"go"},....] pk = obj.get("pk") text = obj.get(filter_field) params[filter_field] = text # 過濾字段:當前對象字段值
cid = self.request.GET.get(filter_field, 0) 因而可知cid是get請求傳遞的值,以前默認都是pk值,如今有多是pk值也多是"python"等普通字段。所以須要調整cid判斷:
if cid == str(pk) or cid == text: # get請求數據int轉換後與對象主鍵值匹配,匹配成功添加active類 link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, text) else: # print(obj) # 蘋果出版社 香蕉出版社 alex egon # print(type(obj)) # <class 'app01.models.Publish'> <class 'app01.models.Author'> link_tag = "<a href='?%s'>%s</a>" % (_url, text) # print(link_tag) # <a href=>蘋果出版社</a> temp.append(link_tag)
list_view.html:
<div class="col-md-3"> {% if showlist.config.list_filter %} {# list_filter有值才顯示FILTER #} <div class="filter"> <h4>Filter</h4> {% for filter_field, linktags in show_list.get_filter_linktags.items %} <div class="well"> {# upper方法改成大寫 #} <p>{{ filter_field.upper }}</p> {% for link in linktags %} <p>{{ link|safe }}</p> {% endfor %} </div> {% endfor %} </div> {% endif %} </div>