组合搜索

做博客后台时,需要根据文章的类型做不同的检索

1、简单实现

关联文件

from django.conf.urls import url
from . import viewsurlpatterns = [url(r'^index.html/$',views.index),url(r'^article/(?P<article_type>\d+)-(?P<category>\d+).html/$',views.article)
]

url.py

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.condition a{display:inline-block;padding: 3px 5px;border: 1px solid black;}.condition a.active{background-color: brown;}</style>
</head>
<body><h2>过滤条件</h2><div class="condition">{% if kwargs.article_type == 0 %}<a href="/article/0-{{ kwargs.category }}.html" class="active">全部</a>{% else %}<a href="/article/0-{{ kwargs.category }}.html">全部</a>{% endif %}{% for row in article_type %}{% if row.id == kwargs.article_type %}<a class="active" href="/article/{{ row.id }}-{{ kwargs.category }}.html">{{ row.caption }}</a>{% else %}<a  href="/article/{{ row.id }}-{{ kwargs.category }}.html">{{ row.caption }}</a>{% endif %}{% endfor %}</div><div class="condition">{% if kwargs.category == 0 %}<a class="active" href="/article/{{ kwargs.article_type }}-0.html">全部</a>{% else %}<a href="/article/{{ kwargs.article_type }}-0.html">全部</a>{% endif %}{% for row in category %}{% if row.id == kwargs.category %}<a class="active" href="/article/{{ kwargs.article_type }}-{{ row.id }}.html">{{ row.caption }}</a>{% else %}<a href="/article/{{ kwargs.article_type }}-{{ row.id }}.html">{{ row.caption }}</a>{% endif %}{% endfor %}</div><h2>查询结果</h2><ul>{% for row in articles %}<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type.caption }}]-[{{ row.category.caption }}]</li>{% endfor %}</ul>
</body>
</html>

article.html

数据库结构:

from django.db import models# Create your models here.class Categoery(models.Model):caption = models.CharField(max_length=16)class ArticleType(models.Model):caption = models.CharField(max_length=16)class Article(models.Model):title = models.CharField(max_length=32)content = models.CharField(max_length=255)category = models.ForeignKey(Categoery)article_type = models.ForeignKey(ArticleType)

处理文件:

from . import  models
def article(request,*args,**kwargs):search_dict = {}for key,value in kwargs.items():kwargs[key] = int(value)        # 把字符类型转化为int类型 方便前端做if a == b  这样的比较if value !='0':search_dict[key] = valuearticles = models.Article.objects.filter(**search_dict) # 字典为空时表示搜索所有article_type = models.ArticleType.objects.all()category = models.Categoery.objects.all()return render(request,'article.html',{'articles':articles,'article_type':article_type,'category':category ,'kwargs':kwargs})

注:实现此功能并不难,最重要的是理清里面的思路;首先先要确定url访问路径格式http://127.0.0.1:8000/article/0-0.html ,第一个0表示article_type字段,第二个0表示category字段,如果为零时,表示搜索此字段全部信息,确认好这个,是成功的第一步,处理文件上有检索的处理;第二个关键点是生成字典search_dict进行相关的搜索,如果是0表示搜索全部;第三个关键点,也是很巧妙的一个方式,把参数kwargs再次传到前端,简直神来之笔!

2、另一种尝试(加载内存调优)

由于ArticleType类型是博客定死的数据,后期不会做变动,可以把数据加载到内存当中,加快查询速度

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.condition a{display:inline-block;padding: 3px 5px;border: 1px solid black;}.condition a.active{background-color: brown;}</style>
</head>
<body><h2>过滤条件</h2><div class="condition">{% if kwargs.article_type_id == 0 %}<a href="/article/0-{{ kwargs.category_id }}.html" class="active">全部</a>{% else %}<a href="/article/0-{{ kwargs.category_id }}.html">全部</a>{% endif %}{% for row in article_type%}{% if row.0 == kwargs.article_type_id %}<a class="active" href="/article/{{ row.0 }}-{{ kwargs.category_id }}.html">{{ row.1 }}</a>{% else %}<a  href="/article/{{ row.0 }}-{{ kwargs.category_id }}.html">{{ row.1 }}</a>{% endif %}{% endfor %}</div><div class="condition">{% if kwargs.category_id == 0 %}<a class="active" href="/article/{{ kwargs.article_type_id }}-0.html">全部</a>{% else %}<a href="/article/{{ kwargs.article_type_id }}-0.html">全部</a>{% endif %}{% for row in category %}{% if row.id == kwargs.category_id %}<a class="active" href="/article/{{ kwargs.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>{% else %}<a href="/article/{{ kwargs.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>{% endif %}{% endfor %}</div><h2>查询结果</h2><ul>{% for row in articles %}<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type }}]-[{{ row.category.caption }}]</li>{% endfor %}</ul>
</body>
</html>

article.html

from django.shortcuts import render
from django.shortcuts import HttpResponse# Create your views here.def index(request):return HttpResponse('Ok')from . import  models
def article(request,*args,**kwargs):search_dict = {}for key,value in kwargs.items():kwargs[key] = int(value)        # 把字符类型转化为int类型 方便前端做if a == b  这样的比较if value !='0':search_dict[key] = valueprint(kwargs)articles = models.Article.objects.filter(**search_dict) # 字典为空时表示搜索所有
article_type = models.Article.type_choiceprint(article_type)category = models.Categoery.objects.all()return render(request,'article.html',{'articles':articles,'article_type':article_type,'category':category ,'kwargs':kwargs})

处理文件.py

数据库文件:

from django.db import models
# Create your models here.
class Categoery(models.Model):caption = models.CharField(max_length=16)# class ArticleType(models.Model):
#     caption = models.CharField(max_length=16)class Article(models.Model):title = models.CharField(max_length=32)content = models.CharField(max_length=255)category = models.ForeignKey(Categoery)# article_type = models.ForeignKey(ArticleType)type_choice  = [(1,'Python'),(2,'Linux'),(3,'大数据'),(4,'架构'),]article_type_id = models.IntegerField(choices=type_choice)

  

3、利用simple_tag把代码优化 

关联文件

from django.db import models
# Create your models here.
class Categoery(models.Model):caption = models.CharField(max_length=16)class ArticleType(models.Model):caption = models.CharField(max_length=16)class Article(models.Model):title = models.CharField(max_length=32)content = models.CharField(max_length=255)category = models.ForeignKey(Categoery)article_type = models.ForeignKey(ArticleType)# type_choice  = [#     (1,'Python'),#     (2,'Linux'),#     (3,'大数据'),#     (4,'架构'),# ]# article_type_id = models.IntegerField(choices=type_choice)

数据库文件.py

from django.shortcuts import render
from django.shortcuts import HttpResponse# Create your views here.def index(request):return HttpResponse('Ok')from . import models
def article(request, *args, **kwargs):search_dict = {}for key, value in kwargs.items():kwargs[key] = int(value)  # 把字符类型转化为int类型 方便前端做if a == b  这样的比较if value != '0':search_dict[key] = valuearticles = models.Article.objects.filter(**search_dict)  # 字典为空时表示搜索所有
article_type = models.ArticleType.objects.all()print(article_type)category = models.Categoery.objects.all()return render(request, 'article.html', {'articles': articles,'article_type': article_type,'category': category,'kwargs': kwargs})

处理文件.py

{% load filter %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.condition a{display:inline-block;padding: 3px 5px;border: 1px solid black;}.condition a.active{background-color: brown;}</style>
</head>
<body><h2>过滤条件</h2><div class="condition">{% filter_all  kwargs 'article_type'%}{% filter_single article_type kwargs 'article_type'%}</div><div class="condition">{% filter_all  kwargs 'category'%}{% filter_single category kwargs 'category'%}</div><h2>查询结果</h2><ul>{% for row in articles %}<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type.caption }}]-[{{ row.category.caption }}]</li>{% endfor %}</ul>
</body>
</html>

article.html

创建templatetags目录,在目录下创建filter.py文件:

from django import template
from django.utils.safestring import mark_safe
register = template.Library()@register.simple_tag
def filter_all(kwargs,type_str):print(type_str)if type_str == 'article_type':if kwargs['article_type'] == 0:tmp = '<a href = "/article/0-%s.html" class ="active" > 全部 </a>'%(kwargs['category'])else:tmp = '<a href = "/article/0-%s.html"> 全部 </a>'%(kwargs['category'])elif type_str == 'category':if kwargs['category'] == 0:tmp = '<a href = "/article/%s-0.html" class ="active" > 全部 </a>' % (kwargs['article_type'])else:tmp = '<a href = "/article/%s-0.html"> 全部 </a>' % (kwargs['article_type'])return mark_safe(tmp)@register.simple_tag()
def filter_single(type_obj,kwargs,type_str):print(type_str)tmp = ''if type_str == 'article_type':for row in type_obj:if row.id == kwargs['article_type']:tag = '<a class="active" href="/article/%s-%s.html">%s</a>\n'%(row.id,kwargs['category'],row.caption)else:tag = '<a href="/article/%s-%s.html">%s</a>\n' % (row.id, kwargs['category'],row.caption)tmp +=tagelif type_str == 'category':for row in type_obj:if row.id == kwargs['category']:tag = '<a class="active" href="/article/%s-%s.html">%s</a>\n' % (kwargs['article_type'],row.id, row.caption)else:tag = '<a href="/article/%s-%s.html">%s</a>\n' % (kwargs['article_type'], row.id, row.caption)tmp += tagreturn mark_safe(tmp)

HTML文件主体内容:

{% load filter %}
<body><h2>过滤条件</h2><div class="condition">{% filter_all  kwargs 'article_type'%}{% filter_single article_type kwargs 'article_type'%}</div><div class="condition">{% filter_all  kwargs 'category'%}{% filter_single category kwargs 'category'%}</div><h2>查询结果</h2><ul>{% for row in articles %}<li>{{ row.id }}-{{ row.title }}------[{{ row.article_type.caption }}]-[{{ row.category.caption }}]</li>{% endfor %}</ul>
</body>

  

JSONP

  JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

原理:

  • - 创建script标签
  • - src=远程地址
  • - 返回的数据必须是js格式
  • - 只能发GET请求

1、什么是同源策略? 

处理文件:

import requests
def jsonp(request):# 获取url信息response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301') response.encoding = 'utf-8'     # 进行编码return render(request,'jsonp.html',{'result':response.text})  # response.text 请求内容

HTML文件:

<body><h1>后台获取的结果</h1>{{ result }}<h1>js直接获取结果</h1><input type="button" value="获取数据" οnclick="getContent();" /><div id="container"></div><script src="/static/jquery-1.8.2.js"></script><script>function getContent() {var xhr = new XMLHttpRequest();         // 创建对象xhr.open('GET', 'http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301'); // GET方式打开xhr.onreadystatechange = function () {  // 收到返回值时执行console.log(xhr.responseText);};xhr.send()  // 发送}</script>
</body>

注:点击js直接获取结果时,浏览器显示下面报错信息,由于浏览器只接受http://127.0.0.1:8000发过来的信息,对于天气网站发过来的信息直接屏蔽掉了,这就是同源策略,那有没有什么方式可以解决?

XMLHttpRequest cannot load http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access.

2、巧用script标签src属性

script标签不受同源策略的影响

处理文件:

import requests
def jsonp(request):# 获取url信息response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301')response.encoding = 'utf-8'     # 进行编码return render(request,'jsonp.html',{'result':response.text})  # response.text 请求内容def jsonp_api(request):return HttpResponse('alert(123)')

HTML文件:

<body><h1>后台获取的结果</h1>{{ result }}<h1>js直接获取结果</h1><input type="button" value="获取数据" οnclick="getContent();" /><div id="container"></div><script>function getContent() {var tag = document.createElement('script');tag.src = '/jsonp_api.html';document.head.appendChild(tag);//   document.head.removeChild(tag);}</script>
</body>

注:js请求时为了方便,还是请求的是当前程序url;执行完上面代码会发现一个神奇的状况,页面会弹出123信息,表明script获取信息成功  

3、对前后端稍加改造,使用方法更加动态化

处理文件:

def jsonp(request):return render(request,'jsonp.html')  # response.text 请求内容def jsonp_api(request):func = request.GET.get('callback')  # 获取用户callback参数content = '%s(10000)'%func          # 执行func(10000)函数return HttpResponse(content)

HTML文件:  

<body><h1>后台获取的结果</h1>{{ result }}<h1>js直接获取结果</h1><input type="button" value="获取数据" οnclick="getContent();" /><div id="container"></div><script>function getContent() {var tag = document.createElement('script');tag.src = '/jsonp_api.html?callback=list';  // 自定义callback参数,与后台达成默契document.head.appendChild(tag);//   document.head.removeChild(tag);}function list(arg){         // 自定义函数与callback=list相对应alert(arg);}</script>
</body>

注:js发请求时,带上callback参数,然后定义参数对应的方法,后台会把数据传入此方法内并且执行执行;至于要打印还是弹框,就看用户自己的需求去处理了;jsonp的原理和实现过程就是上述代码的实现

4、实例应用+ajax

处理文件:

import requests
def jsonp(request):response = requests.get('http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403')response.encoding = 'utf-8'  # 进行编码    return render(request, 'jsonp.html', {'result': response.text})  # response.text 请求内容

HTML文件:

<body><h1>后台获取的结果</h1>{{ result }}<h1>js直接获取结果</h1><input type="button" value="获取数据" οnclick="getContent();" /><div id="container"></div><script src="/static/jquery-1.8.2.js"></script><script>function getContent() {$.ajax({url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403',type: 'POST',dataType: 'jsonp',     // 即使写的type是POST也是按照GET请求发送jsonp: 'callback',jsonpCallback: 'list'});}function list(arg){         // 自定义函数与callback=list相对应console.log(arg);var data = arg['data'];for(k in data){var tr = document.createElement('td');var week = data[k]['week'];var list = data[k]['list'];tr.textContent =weekdocument.body.appendChild(tr);console.log(week);for(i in list){var name = list[i]['name'];console.log(name)}}}</script>
</body>

list({data:[ { "week":"周日", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] }, { "week":"周一", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周二", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周三", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周四", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周五", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] },{ "week":"周六", "list":[ { "time":"0030", "name":"通宵剧场六集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0530", "name":"《都市现场》60分钟精编版(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0630", "name":"《快乐生活一点通》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0700", "name":"《e早晨报》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"0800", "name":"精选剧场四集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1120", "name":"《地宝当家》(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1200", "name":"《都市60分》60分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1300", "name":"《谁是赢家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1400", "name":"女性剧场三集连播", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1700", "name":"《快乐生活一点通》精编版", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1730", "name":"《地宝当家》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1800", "name":"《都市现场》90分钟直播版块", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"1930", "name":"《都市情缘》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2000", "name":"《晚间800》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2020", "name":"《都市剧场》黄金剧(第1集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2110", "name":"《都市剧场》黄金剧(第2集)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2200", "name":"《拍案》", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2230", "name":"江西新闻联播(重播)", "link":"http://www.jxntv.cn/live/jxtv2.shtml" }, { "time":"2250", "name":"都市晚剧场", "link":"http://www.jxntv.cn/live/jxtv2.shtml" } ] }] });

网站获取到的数据

注:实现的过程跟第3自己写的代码一毛一样,也是创建个script然后再删除

XSS过滤

  博客后台中的栗子,用户创建文章的内容时,是不允许让用户提交<script>alert(123)</script>这样的代码;普通编辑模式下,用户写入<script>代码块,不会有什么影响,因为后台会把<script>代码块当成字符串进行前端显示;但是,如果在html源码编辑下,是不能让<script>标签在前端进行显示的,这时就需要用到XSS过滤,把一些特殊标签进行过滤掉

1、简单的标签过滤

依赖模块BeautifulSoup

pip install beatifulsoup4   模块安装

html = '''
<p class="story"><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<div name='root'>Once upon a time there w</div>
</p>
<p><div>Once upon a time there w</div>
</p>
<script>alert(123)</script>
'''

html字符串内容

① 清空<script>标签、a标签的class属性:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'html.parser')   # html.parser内部解析器 会把字符串转化成有结构的文档
tag = soup.find('script')       # tag <script>alert(123)</script> 找到的标签
tag.hidden = True               # <script>标签消失
tag.clear()                     # 清空标签内容a = soup.find('a')              # 删除a标签的class属性
del a.attrs['class']         # {'href': 'http://example.com/lacie', 'id': 'link2', 'class': ['sister']}content = soup.decode()         # 把对象转化为字符串
print(content)
'''
<p class="story">
<a href="http://example.com/lacie" id="link2">Lacie</a> and<div name="root">Once upon a time there w</div>
</p>
<p>
<div>Once upon a time there w</div>
</p>
'''

②  通过白名单进行操作:

from bs4 import BeautifulSoup
tags ={              # 设置白名单'p':['class'],'div':['id']
}
soup = BeautifulSoup(html,'html.parser')    # html.parser内部解析器 会把字符串转化成有结构的文档
for tag in soup.find_all():                 # tag.name 先找子子孙孙、然后再往下找if tag.name in tags:                    # p a div p div script   一次循环的标签for k in list(tag.attrs.keys()):        # 不在白名单对应的属性进行删除if k not in tags[tag.name]:del tag.attrs[k]else:                                   # 不在白名单的标签删除tag.hidden = Truetag.clear()content = soup.decode()         # 把对象转化为字符串
print(content)'''
<p class="story">and<div>Once upon a time there w</div>
</p>
<p>
<div>Once upon a time there w</div>
</p>
'''

2、博客XSS过滤 

XSSFilter文件:

from bs4 import BeautifulSoupclass XSSFilter(object):__instance = Nonedef __init__(self):# XSS白名单self.valid_tags = {"font": ['color', 'size', 'face', 'style'],'b': [],'div': [],"span": [],"table": ['border', 'cellspacing', 'cellpadding'],'th': ['colspan', 'rowspan'],'td': ['colspan', 'rowspan'],"a": ['href', 'target', 'name'],"img": ['src', 'alt', 'title'],'p': ['align'],"pre": ['class'],"hr": ['class'],'strong': []}def __new__(cls, *args, **kwargs):"""单例模式:param cls::param args::param kwargs::return:"""if not cls.__instance:obj = object.__new__(cls, *args, **kwargs)cls.__instance = objreturn cls.__instancedef process(self, content):soup = BeautifulSoup(content, 'html.parser')# 遍历所有HTML标签for tag in soup.find_all(recursive=True):# 判断标签名是否在白名单中if tag.name not in self.valid_tags:tag.hidden = Trueif tag.name not in ['html', 'body']:tag.hidden = Truetag.clear()continue# 当前标签的所有属性白名单attr_rules = self.valid_tags[tag.name]keys = list(tag.attrs.keys())for key in keys:if key not in attr_rules:del tag[key]return soup.decode()

调用方式:

 content = form.cleaned_data.pop('content')      # 移出 content需要在表ArticleDetail上手动添加、关联Articlecontent = XSSFilter().process(content)           # 对content进行数据过滤  过滤到script等标签

上面代码用到了面向对象的单例模式-》》http://www.cnblogs.com/lianzhilei/p/5838821.html

  

  

  

《第二十五章》

转载于:https://www.cnblogs.com/lianzhilei/p/6420445.html

Python开发【Django】:组合搜索、JSONP、XSS过滤相关推荐

  1. Python开发-Django快速入门

    如果你是一位python开发初学者,而且你对Django一无所知,那下面介绍的内容将会是你所需要知道的关于 Django 的知识. 一.快速入门 你是刚学 Python.Django 或是初学编程吗? ...

  2. stark组件开发之组合搜索基本显示

    数据的获取,上一篇,已经有了!然后就是,如何进行展示的问题. 到了展示这里,又有了新的问题, 因为从数据库,取得的数据. 分为 queryset 和 tuple 两种数据结构. tuple 中,只是字 ...

  3. Python开发-Django安全

    安全 在 Web 应用的发展中,安全是最重要主题,Django 提供了多种保护手段和机制. 一.安全概览 Django 的安全性 Django 安全特性的概述.包含保障那些用 Django 建立的网站 ...

  4. win10+python开发django项目day03

    一.创建django项目 1.进入虚拟环境创建django项目 cd Python\envdjango01\Scripts activate cd .. #创建django项目 django-admi ...

  5. Python开发-Django 开源项目

    Django 开源项目 了解 Django 项目本身的开发进程以及你如何为 Django 做贡献: 一.社区: 如何参与其中 为 Django 做贡献 Django 是一个以志愿者为生的社区.随着它的 ...

  6. python(Django之组合搜索、JSONP、XSS过滤 )

    一.组合搜索 二.jsonp 三.xss过滤 一.组合搜索 首先,我们在做一个门户网站的时候,前端肯定是要进行搜索的,但是如果搜索的类型比较多的话,怎么做才能一目了然的,这样就引出了组合搜索的这个案例 ...

  7. python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))...

    昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据.StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对象 ...

  8. Python+Django+Mysql开发在线美食推荐网 协同过滤推荐算法在美食网站中的运用 基于用户、物品的协同过滤推荐算法 个性化推荐算法、机器学习、分布式大数据、人工智能开发

    Python+Django+Mysql开发在线美食推荐网 协同过滤推荐算法在美食网站中的运用 基于用户.物品的协同过滤推荐算法 个性化推荐算法.机器学习.分布式大数据.人工智能开发 FoodRecom ...

  9. 在线图书推荐网 Python+Django+Mysql开发技术 个性化图书推荐系统 协同过滤推荐算法在图书网站中的运用 基于用户、物品的协同过滤推荐算法 个性化推荐算法、机器学习、分布式大数据、人工智

    在线图书推荐网 Python+Django+Mysql开发技术 个性化图书推荐系统 协同过滤推荐算法在图书网站中的运用 基于用户.物品的协同过滤推荐算法 个性化推荐算法.机器学习.分布式大数据.人工智 ...

最新文章

  1. dojo helloworld
  2. Minio分布式集群示例:8个节点,每节点1块盘
  3. 随机过程及其稳态stability
  4. bash 学习笔记2
  5. C语言经典弱智问题解法整理
  6. idea(2021.3)上配置struts框架步骤
  7. c语言网页版在线编译器_C语言快速入门技巧
  8. 云计算里的家校互联平台
  9. 神经网络与深度学习pdf下载
  10. python中字符串以什么结尾_python判断字符串以什么结尾的实例方法
  11. 前端工程师未来发展方向
  12. 网页头部的声明怎么写?
  13. 关于页眉的奇偶页不同设置和奇数页页眉展示每一章名称的设置方法
  14. [译]How browsers work
  15. 快速抢占Shopee墨西哥广告蓝海,Shopee广告投放策略分享
  16. 一桩VIM引发的血案
  17. 黑苹果之联想Y430P亮度记忆功能
  18. error:command ‘gcc‘ failed with exit status 1 记录
  19. 开运算和闭运算的异同
  20. win10任务栏网络连接图标消失的解决办法

热门文章

  1. 求球体的表面积,体积公式
  2. 将https安全证书导入jdk中
  3. 全球及中国表面保护胶带行业研究及十四五规划分析报告
  4. c语言的内存布局规律
  5. 基于STM8的数字温度计设计
  6. 论文阅读23 - Mixture Density Networks(MDN)混合密度网络理论分析
  7. 学习工行MySQL研发管控和治理实践的过程
  8. 北京大学肖臻老师《区块链技术与应用》ETH笔记 - 8.0 ETH挖矿难度的调整
  9. 中国风网站建设设计的2大要素
  10. C语言中打印图形问题