Xadmin顯示視圖


1.display顯示要設置的字段

1. 自定義樣式類,顯示出要顯示的字段,在這個類中,也可以設置對應函數。 list_display=[check,"title",delete]
2.在 Modelxadmin中設置:list_display=["__str__"]
設置Modelxadmin的靜態屬性,即當注冊的對象沒使用樣式類時,使用Modelxadmin的樣式屬性
3.處理表頭
display中的函數名或者變量名作為表頭
1.需要判斷傳的列表中的內容是函數名還是字符串
2.如果是字符串,判斷是"__str__"還是其他的
3.讓相應的字符串表頭顯示對應的中文,取到字段對象,引用字段中的verbose_name
4.處理表單數據
需要判斷傳的列表中的內容是函數名還是字符串
1.若是函數名,去執行對應的函數,取到對應的值
2.若是變量,利用反射到相應的數據中取到值

2.設定樣式類list_display

from Xadmin.service.Xadmin import site,Modelxadmin
from app01 import models
from django.utils.safestring import  mark_safe
class BookConfig(Modelxadmin):
    href=change/'%s/'自動在當前路徑后拼接路徑
    def edit(self, obj=None,  is_header=False):
        if is_header:  # 此時作表頭處理
            return "操作"
        return mark_safe("<a href='change/%s/'>編輯</a>"%obj.pk)
    def delete(self, obj=None, is_header=False):
        if is_header:  # 此時作表頭處理
            return "刪除"
        return mark_safe("<a href='del/%s/'>刪除</a>" % obj.pk)
    def check(self, obj=None, is_header=False):
        if is_header:  # 此時作表頭處理
            return "選擇"
        return mark_safe("<input type='checkbox'>")
    list_display=[check,"title","price","publish","authors",edit,delete]
site.register(models.Book,BookConfig)
View Code

3.顯示設置

1.處理表頭

處理表頭 [check,'title', 'prcie',edit]
# 1.需要判斷傳的列表中的內容是函數名還是字符串
# 2.如果是字符串,判斷是"__str__"還是其他的
 head=[]
        for field in self.list_display:
            if isinstance(field,str):
               if field=="__str__":
                   val=self.model._meta.model_name.upper()  #如果沒定義樣式類,表頭就顯示操作表的名字的大寫
               else:
                   # class Book(models.Model):
                   #     title = models.CharField(max_length=32, verbose_name="書名")
                   #     price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="價格")
                   #如果是字段字符串,讓表頭顯示其定義的中文表頭。title是字段對象,找到title后title.verbose_name 獲取這個屬性值
                   obj=self.model._meta.get_field(field)
                   val=obj.verbose_name
            else:
                val = field(self,is_header=True)
            head.append(val)
View Code

2.處理表單數據

使用反射
        data_list=self.model.objects.all() #取出每一條數據的對象,data_list[0].字段名(title) 就能得到相應的數據
        content = []
        for obj in data_list:
            temp=[]
            for field in self.list_display:#自定義的樣式類中有可能放的是自定義的函數名[check,'title', 'prcie',edit]
                #需要判斷傳的列表中的內容是函數名還是字符串
                if isinstance(field,str): #判斷數據類型
                   val=getattr(obj,field)  #相當於obj.title,obj.price 其中obj.__str__會自動觸發這個方法
                   print("結果是:",val)
                else:
                    val=field(self,obj,) #定義的方法,obj為這個方法執行的哪條數據對象
                temp.append(val)
            content.append(temp)
        return render(request,"list.html",{"content":content,"head":head,"type":type})
View Code

4.利用反向路由解析得到路徑

'''
#Modelxadmin中設置
class Modelxadmin(object):
    list_display=["__str__"] #設置Modelxadmin的靜態屬性,即當注冊的對象沒使用樣式類時,使用Modelxadmin的樣式屬性
    def __init__(self,model,site):  #如果傳的是book,model就是Book 傳的是publish,model就是Publiah
        self.model=model
        self.site=site
        self.model_name = self.model._meta.model_name #得到app名
        self.app_name = model._meta.app_label  #得到表名
        #為路由設置別名:
            def get_url_2(self):
        temp = []
        # print("=====",model_name )
        # temp.append(url(r"^$", self.list_view))
        temp.append(url(r"^$", self.list_view,name="{}/{}_list".format( self.app_name, self.model_name)))
        temp.append(url(r"^add/$", self.add_view,name="{}/{}_add".format( self.app_name, self.model_name)))
        # temp.append(url(r"^(\d+)/change/$", self.change_view,))
        temp.append(url(r"^change/(\d+)/$", self.change_view,name="{}/{}_change".format( self.app_name, self.model_name) ))
        temp.append(url(r"^del/(\d+)/$", self.del_view,name="{}/{}_del".format( self.app_name, self.model_name)))
        return temp
#自定以樣式類中設置:
from django.utils.safestring import  mark_safe
from django.urls import reverse
class BookConfig(Modelxadmin):
    def edit(self, obj=None,  is_header=False):
        if is_header:  # 此時作表頭處理
            return "操作"          #BookConfig中沒有self.app_name,就去Modelxadmin找
        url_name="{}/{}_change".format( self.app_name, self.model_name)
        v = reverse(url_name, args=(obj.pk,))
        return mark_safe("<a href='%s'>編輯</a>" % v)
'''
View Code

顯示頁面的html

'''
<p>
    <span>序號</span>
    {% for foo in head %}
        <span>{{ foo }}</span>
    {% endfor %}
</p>

{% for foo in content %}
    <P>
      <span>{{ forloop.counter }}</span>
      {% for foo1 in foo %}
       <span>{{ foo1 }}</span>
    {% endfor %}
    </P>
{% endfor %}
'''

5.顯示多對多的關系字段

多對多的字段,傳過去之后在頁面上顯示字符串:app01.Author.None
例:作者是多對多的關系
 list_display=[check,"title","price","publish","authors",edit,delete]
 傳過去之后在頁面上顯示字符串:app01.Author.None
解決方法一:將ManytoMany這個字段當作函數名傳過去,不再寫成字符串
在樣式類中定義ManytoMany字段方法:
    def display_authors(self,obj=None, is_header=False):
        if is_header:
            return "作者名稱"
        s=[]
        for author in obj.authors.all(): #必須使用all(),得到所有的作者對象
            s.append(author.name) #取出每個作者對象的name屬性
        val=" | ".join(s)
        return mark_safe(val)

    list_display = [check, "title", "price", "publish", display_authors, edit, delete]
方法二:判斷是不是ManytoMany類型
        data_list=self.model.objects.all() #取出每一條數據的對象,data_list[0].字段名(title) 就能得到相應的數據
        content = []
        for obj in data_list:
            temp=[]
            for field in self.list_display:#自定義的樣式類中有可能放的是自定義的函數名[check,'title', 'prcie',edit]
                #需要判斷傳的列表中的內容是函數名還是字符串
                if isinstance(field,str): #判斷數據類型
                    #處理多對多的字段方法二:判斷是不是ManytoMany類型
                    from django.db.models.fields.related import ManyToManyField
                    many_obj = self.model._meta.get_field(field) #取到字段對象
                    if isinstance(many_obj,ManyToManyField):
                        t=[]
                        for i in getattr(obj,field).all():
                            t.append(i.name)
                        val=" | ".join(t)
                    else:val=getattr(obj,field)  #相當於obj.title,obj.price 其中obj.__str__會自動觸發這個方法
list_display=[check,"title","price","publish","authors",edit,delete]
View Code

6.將刪除,編輯,選擇按鈕封裝起來

'''
app01.Xadmin 
1.使用繼承:但是需要在每個樣式類中設定
class Operation():
    def edit(self, obj,is_header):
        if is_header:  # 此時作表頭處理
            return "操作"
        else:
            url_name = "{}/{}_change".format(self.app_name, self.model_name)  # BookConfig中沒有self.app_name,就去Modelxadmin找
            v = reverse(url_name, args=(obj.pk,))
            return mark_safe("<a href='%s'>編輯</a>" % v)
    def delete(self, obj, is_header):
        if is_header:  # 此時作表頭處理
            return "操作"
        return mark_safe("<a href='del/%s/'>刪除</a>" % obj.pk)

    def check(self, obj, is_header):
        if is_header:  # 此時作表頭處理
            return "選擇"
        else:print(777)
        return mark_safe("<input type='checkbox'>")
class BookConfig(Modelxadmin, Operation):
    def check(self,obj=None, is_header=False):return super().check(obj, is_header)
    def edit(self,obj=None, is_header=False):return super().edit(obj, is_header)
    def delete(self,obj=None,  is_header=False):return super().delete(obj, is_header)
    list_display=[check,"title","price","publish","authors",edit,delete]
#如果不在BookConfig中定義check,edit,delete函數,在list_dispaly中加函數名后,會顯示未定義。在用super調用時不能傳位置參數
2.在Xadmin中設置,將check,edit,delete加到每個模型表的樣式類中,模型表的樣式類就不用再加這些函數
class Modelxadmin(object):
    # 選擇按鈕  編輯 刪除
    def edit(self, obj=None, is_header=False):
        if is_header:  # 此時作表頭處理
            return "操作"
        else:
            v=self.get_change_url(obj)
            return mark_safe("<a href='%s'>編輯</a>" %v)
    def delete(self, obj=None, is_header=False):
        if is_header:  # 此時作表頭處理
            return "操作"
        v = self.get_del_url(obj)
        return mark_safe("<a href='%s'>刪除</a>" %v)
    def check(self, obj=None, is_header=False):
        if is_header:  # 此時作表頭處理
            return "選擇"
        v = self.get_del_url(obj)
        return mark_safe("<input type='checkbox'>")
    #構建新的list_dispaly
    def new_list_display(self):
        temp=[]
        temp.append(Modelxadmin.check)
        temp.extend(self.list_display)
        temp.append(Modelxadmin.edit)
        temp.append(Modelxadmin.delete)
        return temp
    #處理表頭 [check,'title', 'prcie',edit]
    for field in self.new_list_display():pass
     #處理表單數據,使用反射
      data_list=self.model.objects.all() #取出每一條數據的對象,data_list[0].字段名(title) 就能得到相應的數據
        content = []
        for obj in data_list:
            temp=[]
            for field in self.new_list_display():pass
樣式類中直接傳要顯示的字段 list_display = ["title", "price", "publish", "authors"]
'''
View Code

7.設定樣式類list_display_link

1.在循環表單數據時,如果list_display中的字段名在list_display_link,就將改字段的內容設置成編輯標簽
2.如果表中數據設置成了編輯標簽,那么編輯這個操作就沒什么用了,應該判斷如果樣式中無list_display_link,就顯示編輯操作,
有list_display_link則不顯示編輯操作
在new_list_display中判斷是否加編輯操作
    def new_list_display(self):
        temp=[]
        temp.append(Modelxadmin.check)
        temp.extend(self.list_display)
        #判斷是否加編輯操作
        if not self.list_display_link:
            temp.append(Modelxadmin.edit)
        temp.append(Modelxadmin.delete)
        return temp
##將相應值設置成編輯標簽
from django.db.models.fields.related import ManyToManyField
    try:
        many_obj = self.model._meta.get_field(field) #取到字段對象
        if isinstance(many_obj,ManyToManyField):
            t=[]
            for i in getattr(obj,field).all():
                t.append(i.name)
            val=" | ".join(t)
        else:
            #判斷改字段是否在list_display_link,如果在,就設置成標簽形式,不再就正常顯示
            if field in self.list_display_link:
                edit_url=self.get_change_url(obj)
                val=mark_safe("<a href='%s'>%s</a>"%(edit_url,getattr(obj,field)))
            else:val=getattr(obj,field)
    except Exception as e:
        val = getattr(obj, field)
View Code
顯示頁面的函數形式
'''
 def list_view(self, request): #self是Modelxadmin的實例對象,要么是自定義樣式類的實例對象
    # print("這里是:", model_name )
    type=request.GET.get("name")
    if not type:type=""
    print(type)
    print(self.model)  #用戶調用的哪張表,self.model就是哪張表  <class 'app02.models.Order'>
    print("新的是:",self.new_list_display())
    #處理表頭 [check,'title', 'prcie',edit]
    # 1.需要判斷傳的列表中的內容是函數名還是字符串
    # 2.如果是字符串,判斷是"__str__"還是其他的
    head=[]
    # for field in self.list_display:
    for field in self.new_list_display():
        if isinstance(field,str):
           if field=="__str__":
               print("食物")
               val=self.model._meta.model_name.upper()  #如果沒定義樣式類,表頭就顯示操作表的名字的大寫
           else:
               # class Book(models.Model):
               #     title = models.CharField(max_length=32, verbose_name="書名")
               #     price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="價格")
               #如果是字段字符串,讓表頭顯示其定義的中文表頭。title是字段對象,找到title后title.verbose_name 獲取這個屬性值
               obj=self.model._meta.get_field(field)
               val=obj.verbose_name
        else:
            val = field(self,is_header=True)
        head.append(val)
        print(head)
    #處理表單數據,使用反射
    data_list=self.model.objects.all() #取出每一條數據的對象,data_list[0].字段名(title) 就能得到相應的數據
    content = []
    for obj in data_list:
        temp=[]
        # for field in self.list_display:#自定義的樣式類中有可能放的是自定義的函數名[check,'title', 'prcie',edit]
        for field in self.new_list_display():
            #需要判斷傳的列表中的內容是函數名還是字符串
            if isinstance(field,str): #判斷數據類型
                #處理多對多的字段方法二:判斷是不是ManytoMany類型
                from django.db.models.fields.related import ManyToManyField
                try:
                    #如果是__str__ 走到這會報錯,因此使用拋出異常處理
                    many_obj = self.model._meta.get_field(field) #取到字段對象
                    if isinstance(many_obj,ManyToManyField):
                        t=[]
                        for i in getattr(obj,field).all():
                            t.append(i.name)
                        val=" | ".join(t)
                    else:
                        # val=getattr(obj,field)  #相當於obj.title,obj.price 其中obj.__str__會自動觸發這個方法
                        #判斷改字段是否在list_display_link,如果在,就設置成標簽形式,不再就正常顯示
                        if field in self.list_display_link:
                            edit_url=self.get_change_url(obj)
                            val=mark_safe("<a href='%s'>%s</a>"%(edit_url,getattr(obj,field)))
                        else:val=getattr(obj,field)
                except Exception as e:
                    val = getattr(obj, field)
                print("結果是:",val)
            else:
                val=field(self,obj,) #定義的方法,obj為這個方法執行的哪條數據對象
            temp.append(val)
            print("temp是:", temp)
        content.append(temp)
    print("content是:", content)
    # ##獲取增加頁面的url 點擊增加的時候,跳到增加頁面。自動拼接
    # add_url="add"
    return render(request,"list.html",{"content":content,"head":head,"type":type,"add_url":self.get_add_url()})



'''
View Code

8.設置分頁

將分頁方法設置為顯示類得屬性,用時直接用對象調用

class ShowList(object):
    def __init__(self,config,data_list,request):
        self.config=config  #config是Modelxadmin的對象
        self.data_list=data_list
        self.request=request
    ##配置分頁設置:
        current_page = self.request.GET.get("page")
        pagination = Pagination(current_page, self.data_list.count(), "%s" % self.config.get_list_url(), self.request.GET,
                                per_page_num=3)
        self.pagination=pagination
        self.model_list = self.data_list[pagination.start:pagination.end]
 def get_body(self):
        content = []
        for obj in self.model_list:pass #循環分完頁之后數據對象
View Code
分頁條:
<ul class="pull-right">
{{show_list.pagination.page_html|safe }}
</ul>

9.搜索功能

搜索時用GET請求,后端很根據收到的搜索條件進行處理,在顯示全部數據的基礎上,將符合搜索的內容顯示出來
未使用搜索時,獲得當前對象的所有內容
data_list = self.model.objects.all()
加了搜索,就在這基礎上進行條件搜索,使用filter
data_list = self.model.objects.filter(條件)
獲取到設定的搜索字段,使用Q()進行操作,將字符串類型的字段和接受到的搜索值加到Q()中,搜索時會檢測所有對象的這個字段中是否含有搜索值,如果有,就把這個
對象取出來
class Modelxadmin(object):
    search_fields = []
    def get_search(self, request):
        search_condition = Q()
        search_condition.connector = 'or'
        search_value = request.GET.get("search_value")
        if search_value:
            for search_field in self.search_fields:
                search_condition.children.append((search_field + "__icontains", search_value))
        return search_condition
    def list_view(self, request): #self是Modelxadmin的實例對象,要么是自定義樣式類的實例對象
        #print(self.model)  #用戶調用的哪張表,self.model就是哪張表  <class 'app02.models.Order'>
        search_condition=self.get_search(request)
        data_list = self.model.objects.filter(search_condition) #search_condition有值,就按值搜索,無值就搜索全部
Views.py
在顯示頁面,設置搜索框是否顯示。通過判斷search_fields來判斷是都設置了搜索值,如果為空,在頁面上就不顯示搜索
HTML
'''
{% if  show_list.config.search_fields %}
 <div class="input-group">
     <form action=" " method="GET">
        <span class="input-group-btn">
             <input type="text" name="search_value" class="form-control" placeholder="Search for...">
            <button class="btn btn-default" >搜索</button>
        </span>
     </form>
 </div>
{% endif %}
'''
View Code

10.批處理功能

實現選擇對應得操作后,執行對應得函數
批處理操作使用select選擇的方式:value應對應函數名,顯示的操作名稱不應該直接再HTML中設定,
可以在后端為相應的執行函數起相應的名字
對函數做描述:
foo.short_description="批量初始化" #對這個函數作描述
class A():
    def foo(self,queryset):
        queryset.delete()
    foo.short_description="批量刪除"
    def update(self,queryset):
        queryset.update(price=100)
    update.short_description="批量初始化"  #對這個函數作描述
    action=[foo,update]
b=A()
for i in b.action:   #i是函數名
    print(i.__name__,i.short_description)
HTML中
  <option value="{{ i.__name__ }}">{{ i.short_description) }}</option>
View Code

1.設置批處理函數

在app01 Xadmin中設置自定義處理函數:
class BookConfig(Modelxadmin):
 def all_update(self,request,queryset): #queryset為數據對象
        queryset.update(price=998)
        list_url = self.get_list_url()
        return redirect("%s" % list_url)
    all_update.short_description="批量初始化"
    actions=[all_update,]
在全局中設置批量刪除函數:
class Modelxadmin(object):
actions=[]
  def all_delete(self,request,queryset):
        queryset.delete()
        list_url=self.get_list_url()
        return redirect("%s"%list_url)
    all_delete.short_description="批量刪除"

2.在Modelxadmin將批量刪除和樣式類中的actions合到一起

def get_action(self): #將批量刪除和樣式類中的actions合到一起
        temp=[]
        temp.append(self.all_delete)
        temp.extend(self.actions) #迭代添加
        return temp  
#將得到的temp作為ShowList的一個屬性,並函數名和描述值處理后在頁面顯示出來
class ShowList(object):
self.actions=self.config.get_action()
def new_actions(self):
    temp=[]
    for action in self.actions:
        temp.append({
            "name":action.__name__,
            "desc":action.short_description
        })
    return temp
View Code

3.HTML

<span class="input-group-btn" >
    <select name="action" id="" class="form-control">
        <option value="">------------------</option>
        {% for foo in show_list.new_actions %}
             <option value="{{ foo.name }}">{{foo.desc  }}</option>
        {% endfor %}
    </select>
    <button class="btn btn-default" >GO</button>
</span>

4.后台接收處理:

class Modelxadmin(object):
     def list_view(self, request):
          if request.method=='POST': #批量操作
                action=request.POST.get("action")  #哪種操作,name="action",值為要執行操作的函數名
                print("操作是",action)
                selected_pk=request.POST.getlist("selected") #操作的數據
                action_obj=self.model.objects.filter(pk__in=selected_pk)
                action=getattr(self,action)
                ret=action(request,action_obj)
                return ret

完整的views.py

##批處理:得到注冊對象樣式類中指定的操作,並為所有的注冊對象添加上刪除操作
def all_delete(self,request,queryset):
    queryset.delete()
    list_url=self.get_list_url()
    return redirect("%s"%list_url)
all_delete.short_description="批量刪除"
def get_action(self): #將批量刪除和樣式類中的actions合到一起
    temp=[]
    temp.append(self.all_delete)
    temp.extend(self.actions) #迭代添加
    return temp  #將得到的temp作為ShowList的一個屬性
def list_view(self, request): #self是Modelxadmin的實例對象,要么是自定義樣式類的實例對象
    if request.method=='POST': #批量操作
        action=request.POST.get("action")  #哪種操作
        print("操作是",action)
        selected_pk=request.POST.getlist("selected") #操作的數據
        action_obj=self.model.objects.filter(pk__in=selected_pk)
        action=getattr(self,action)
        ret=action(request,action_obj)
        return ret
View Code

11.過濾功能

1.首先在頁面上展示出過濾的內容

頁面收到后端傳來的數據進行循壞操作,收到的應該是個字典:
{"publish":["a","a"],"author":["a","a"]},key值為表名,value為表中的所有對象的名字,同時將value
設置成標簽,herf設為?key=obj.pk的形式,點完標簽后,后台接受到操作的表名和要操作的對象進行搜索操作,從而展示出來

2.在指定的app01中注冊模型表中設置過濾的字段:以Book表為例:

class BookConfig(Modelxadmin):
    list_filter=["publish","authors"]
在Xadimn中作后台處理操作:
class Modelxadmin(object):
      list_filter = []
 
        
首先要做的是創建出{"publish":["a","a"],"author":["a","a"]}這種類型給頁面展示出來,展示出來之后,在做跳轉操作,展示的處理都放在
ShowList中,在ShowList中定義處理函數。得到自定義的search_fields中,得到對應的字符串類型的字段,根據字符串,找到這個字段對象,根據字段
對象,得到關聯表中的所有對象,將這個對象名做成鏈接返給頁面
1.def get_filter_link_tags(self):
    # link_tags={"publish":["a","a"],"author":["a","a"]}
    link_tags={}
    for filter_field in self.list_filter: #["title", "price"]
        filter_field_obj=self.config.model._meta.get_field(filter_field) #得到Book表中的publish和authors字段
        #得到字段對象關聯表的所有對象。publish和authors中所有對象
        related_data_list=filter_field_obj.rel.to.objects.all()
        temp=[]
        for obj in related_data_list: #對每個對象做處理
            _url="%s=%s"%(filter_field,obj.pk)
            s="<a href='?%s'>%s</a>"%(_url,str(obj)) #在頁面顯示出?publish=2
            temp.append(mark_safe(s))
        link_tags[filter_field]=temp
    return link_tags

3.點擊相應鏈接

在點擊相應鏈接之后,點擊publish中的對象顯示?publish=2這種形式,點擊author中的內容顯示?author=2
但是要保存搜索條件,即在上次選的條件下繼續搜索,達到?publish=2&?author=2的效果。使用request.GET
在第一次點擊鏈接之后,頁面刷新,會重新走到這一步,獲取數據返還給頁面,此時self.request.GET獲取到?publish=2,在執行到循環authors的對象時
就會將參數拼接起來?publish=2&?author=2
def get_filter_link_tags(self):
        # link_tags={"publish":["a","a"],"author":["a","a"]}
        link_tags={}
        from copy import deepcopy
        for filter_field in self.list_filter:
          # /Xadmin/app01/book/?page=2
            params = deepcopy(self.request.GET)  #將后面的參數以字典的形式接收 {'page':2}
            filter_field_obj=self.config.model._meta.get_field(filter_field)
            #得到字段對象關聯表的所有對象
            related_data_list=filter_field_obj.rel.to.objects.all()
            temp=[]
            for obj in related_data_list:
                params[filter_field]=obj.pk # {"authors":2}
                _url=params.urlencode()
                # _url="%s=%s"%(filter_field,obj.pk)
                s="<a href='?%s'>%s</a>"%(_url,str(obj))
                temp.append(mark_safe(s))
                link_tags[filter_field]=temp
        return link_tags
View Code

4.點擊完當前標簽之后,當前標簽添加背景色。通過判斷當前的接受到的id和循環中的當前id是否相等

current_id=self.request.GET.get(filter_field)
if current_id==str(obj.pk):
        s = "<a class='item' href='?%s'>%s</a>" % (_url, str(obj))
else:  
    s="<a href='?%s'>%s</a>"%(_url,str(obj))

5.鏈接跳轉

點擊相應的標簽后,后台接收到?publish=2這個數據,進行過濾查詢,使用Q().children
class Modelxadmin(object):
    filter_condition=Q()
    for filter_field,val in request.GET.items():
        ##當選擇分頁時,頁面上會把page=2傳過來,仍走這一步,但是表中並沒有這個字段,所以會報錯
        if filter_field not in ['page',"search_value"]:
            filter_condition.children.append((filter_field,val))
    data_list = self.model.objects.filter(filter_condition).filter(search_condition) #search_condition有值
View Code

過濾功能views.py

class BookConfig(Modelxadmin):
    list_filter=["publish","authors"]
    
class Modelxadmin(object):
      list_filter = []
      def list_view(self, request): 
       filter_condition=Q()
        for filter_field,val in request.GET.items():
            ##當選擇分頁時,頁面上會把page=2傳過來,仍走這一步,但是表中並沒有這個字段,所以會報錯
            if filter_field not in ['page',"search_value"]:
                filter_condition.children.append((filter_field,val))
        data_list = self.model.objects.filter(filter_condition).filter(search_condition)
         #search_condition有值,就按值搜索,無值就搜索全部
class ShowList(object):
 def get_filter_link_tags(self):
        # link_tags={"publish":["a","a"],"author":["a","a"]}
        link_tags={}
        from copy import deepcopy
        for filter_field in self.list_filter:
            # /Xadmin/app01/book/?page=2
            params = deepcopy(self.request.GET)#將后面的參數以字典的形式接收 {'page':2}
            current_id=self.request.GET.get(filter_field)
            filter_field_obj=self.config.model._meta.get_field(filter_field)
            #得到字段對象關聯表的所有對象
            related_data_list=filter_field_obj.rel.to.objects.all()
            temp=[]
            for obj in related_data_list:
                params[filter_field]=obj.pk # {"authors":2}
                _url=params.urlencode()
                # _url="%s=%s"%(filter_field,obj.pk)
                if current_id==str(obj.pk):
                    s = "<a class='item' href='?%s'>%s</a>" % (_url, str(obj))
                else:  
                    s="<a href='?%s'>%s</a>"%(_url,str(obj))
                temp.append(mark_safe(s))
            link_tags[filter_field]=temp
        return link_tags
        
HTML:
 <div class="col-sm-2">
            {% for filter_filed,link_tag_list in show_list.get_filter_link_tags.items  %}
                <p>By {{ filter_filed.upper }}</p>
                {% for link_tag in link_tag_list  %}
                <p>{{ link_tag }}</p>
                {% endfor %}
            {% endfor %}

        </div>
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM