1.純模板語言實現 2.自定義simpletag實現(本質是簡化了純模板語言的判斷) 原理都是通過django路由系統,匹配url篩選條件,將篩選條件作為資料庫查詢結果,返回給前端。 例如:路由系統中的url格式是這樣: 其中article_type_id和category_id和資料庫中欄位是相對 ...
一、實現方法 |
1.純模板語言實現
2.自定義simpletag實現(本質是簡化了純模板語言的判斷)
二、基本原理 |
原理都是通過django路由系統,匹配url篩選條件,將篩選條件作為資料庫查詢結果,返回給前端。
例如:路由系統中的url格式是這樣:
url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html',views.filter)
其中article_type_id和category_id和資料庫中欄位是相對應的,此時當一個url為article-1-2.html時候,後臺處理函數的參數將是一個字典{'article_type_id': 1, 'category_id': 1},然後將該條件作為資料庫查詢條件,最後得出結果返回給前端
三、代碼樣例 |
方法1:純模板語言實現
urls.py
#!/usr/bin/env python3 #_*_ coding:utf-8 _*_ #Author:wd from django.conf.urls import url from . import views urlpatterns = [ url(r'^$',views.index), url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html',views.filter), ]
models.py
from django.db import models class Category(models.Model): caption=models.CharField(max_length=64) class Article_type(models.Model): caption=models.CharField(max_length=64) class Article(models.Model): title=models.CharField(max_length=64) content=models.CharField(max_length=256) category=models.ForeignKey(to='Category') article_type=models.ForeignKey(to='Article_type'
views.py
def filter(request,*args,**kwargs): if request.method=="GET": condition={} for k,v in kwargs.items(): kwargs[k]=int(v) #模板if判斷row.id是數字,所以這裡需要轉換 if v=="0":#當條件為0代表所選的是全部,那麼就不必要加入到過濾條件中 pass else: condition[k]=int(v) aritcle=models.Article.objects.filter(**condition) aritcle_type=models.Article_type.objects.all() aritcle_category=models.Category.objects.all() return render(request,'search.html',{ 'aritcle':aritcle, 'article_type':aritcle_type, 'article_category':aritcle_category, 'article_arg':kwargs,#將當前的篩選條件傳遞給html })
html模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container a{ display: inline-block; padding: 3px 5px; margin: 5px; border: 1px solid #dddddd ; } .active{ background-color: rebeccapurple; } </style> </head> <body> <h1>搜索條件</h1> <div class="container"> {% if article_arg.article_type_id == 0 %} <a class="active" href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a> {% else %} <a href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a> {% endif %} {% for row in article_type %} {% if row.id == article_arg.article_type_id %} <a class="active" href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a> {% else %} <a href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a> {% endif %} {% endfor %} </div> <div class="container"> {% if article_arg.category_id == 0 %} <a class="active" href="/cmdb/article-{{ article_arg.article_type_id }}-0.html">全部</a> {% else %} <a href="/cmdb/article-{{ article_arg.article_type_id }}-0.html">全部</a> {% endif %} {% for row in article_category %} {% if row.id == article_arg.category_id %} <a class="active" href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a> {% else %} <a href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a> {% endif %} {% endfor %} </div> <h1>查詢結果</h1> <div> {% for row in aritcle %} <div>{{ row.id }}-{{ row.title }}</div> {% endfor %} </div> </body> </html>
方法二:使用simpletag實現
定義simpletag,參考博客Django基礎篇
myfilter.py
#!/usr/bin/env python3 #_*_ coding:utf-8 _*_ #Author:wd from django import template from django.utils.safestring import mark_safe register=template.Library() @register.simple_tag def filter_all(article_arg,condition): ''' 處理條件為全部 :param article_arg: 當前url字典:如{'article_type_id': 1, 'category_id': 1} :param condition: 要處理的條件,如article_type_id,用於區分當前處理選擇了那個全部 :return: 返回下麵頁面形式 {% if article_arg.article_type_id == 0 %} <a class="active" href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a> {% else %} <a href="/cmdb/article-0-{{ article_arg.category_id }}.html">全部</a> {% endif %} {% for row in article_type %} {% if row.id == article_arg.article_type_id %} <a class="active" href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a> {% else %} <a href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a> {% endif %} {% endfor %} ''' if condition=='article_type_id': if article_arg[condition]==0: print(article_arg['category_id']) res= '<a class ="active" href="/cmdb/article-0-%s.html">全部</a>' % article_arg['category_id'] else: res = '<a href="/cmdb/article-0-%s.html">全部</a>' % article_arg['category_id'] return mark_safe(res) elif condition=='category_id': if article_arg['category_id']==0: res = '<a class ="active" href="/cmdb/article-%s-0.html">全部</a>' % article_arg['article_type_id'] else: res = '<a href="/cmdb/article-%s-0.html">全部</a>' % article_arg['article_type_id'] return mark_safe(res) @register.simple_tag def filter_type(article_type,article_arg): ''' :param article_type: article_type對象 :param article_arg: 當前url字典 :return: {% for row in article_type %} {% if row.id == article_arg.article_type_id %} <a class="active" href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a> {% else %} <a href="/cmdb/article-{{ row.id }}-{{ article_arg.category_id }}.html">{{ row.caption }}</a> {% endif %} {% endfor %} ''' res=[] for row in article_type: if row.id== article_arg['article_type_id']: temp='<a class="active" href="/cmdb/article-%s-%s.html">%s</a>' %(row.id,article_arg['category_id'],row.caption) else: temp = '<a href="/cmdb/article-%s-%s.html">%s</a>' % (row.id, article_arg['category_id'],row.caption) res.append(temp) return mark_safe("".join(res)) @register.simple_tag def filter_category(article_category,article_arg): ''' :param article_type: article_category對象 :param article_arg: 當前url字典 :return: {% for row in article_category %} {% if row.id == article_arg.category_id %} <a class="active" href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a> {% else %} <a href="/cmdb/article-{{ article_arg.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a> {% endif %} {% endfor %} ''' res=[] for row in article_category: if row.id== article_arg['category_id']: temp='<a class="active" href="/cmdb/article-%s-%s.html">%s</a>' %(article_arg['article_type_id'],row.id,row.caption) else: temp = '<a href="/cmdb/article-%s-%s.html">%s</a>' % (article_arg['article_type_id'],row.id,row.caption) res.append(temp) return mark_safe("".join(res))
html模板
{% load myfilter %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .container a{ display: inline-block; padding: 3px 5px; margin: 5px; border: 1px solid #dddddd ; } .active{ background-color: rebeccapurple; } </style> </head> <body> <h1>搜索條件</h1> <div class="container"> {% filter_all article_arg 'article_type_id' %} {% filter_type article_type article_arg %} </div> <div class="container"> {% filter_all article_arg 'category_id' %} {% filter_category article_category article_arg %} </div> <h1>查詢結果</h1> <div> {% for row in aritcle %} <div>{{ row.id }}-{{ row.title }}</div> {% endfor %} </div> </body> </html>
ps附上簡圖:
四、其他變化 |
在如上的示例中,我們的過濾條件是從資料庫中拿到,有時候我們定義的時候使用的是靜態欄位,此時組合搜索會稍微修改。
1.model定義
class Article(models.Model): title=models.CharField(max_length=64) content=models.CharField(max_length=256) category=models.ForeignKey(to='Category') article_type=( #使用靜態欄位放入記憶體 (1,'linux'), (2,'python'), (3,'go'), )
2.處理函數變化
###獲取#### aritcle_type=models.Article.article_type#直接獲取類的靜態欄位
3.simpletag相應改變
###由於我們傳遞的元祖,所以取值使用元祖方式 article_type[0]# 篩選條件id article_type[1]# 篩選條件名稱