Django——组合搜索,jsonp,xss过滤(bs4),单例模式

组合搜索

方法一:

models.py

views.py

url.py

html

1 url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html', views.article),
url.py
 1 from django.db import models
 2 
 3 # Create your models here.
 4 class Category(models.Model):
 5     caption = models.CharField(max_length=16)
 6 
 7 class ArticleType(models.Model):
 8     caption = models.CharField(max_length=16)
 9 
10 class Article(models.Model):
11     title = models.CharField(max_length=32)
12     content = models.CharField(max_length=255)
13     category = models.ForeignKey('Category')
14     article_type = models.ForeignKey('ArticleType')
15   
models.py
 1 from django.shortcuts import render
 2 from cmdb import models
 3 # Create your views here.
 4 
 5 def article(request,*args,**kwargs):
 6     condition = {}
 7     for k,v in kwargs.items():
 8         kwargs[k] = int(v)      # 数据库中id是int型 所以要转成int型发送到前端
 9         if v == '0':
10             pass
11         else:
12             condition[k] = v
13     article_type_list = models.ArticleType.objects.all()
14     category_list = models.Category.objects.all()
15     result = models.Article.objects.filter(**condition)
16 
17     return render(request,'article.html',{'result':result,'article_type_list':article_type_list,
18                                           'category_list':category_list,'arg_dict':kwargs})
Views.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         .condition a{
 8             display: inline-block;
 9             padding: 3px 5px;
10             margin: 5px;
11             border: 1px solid #dddddd;
12         }
13         .condition a.active{
14             background-color: gold;
15             color: red;
16         }
17     </style>
18 </head>
19 <body>
20     <h1>过滤条件</h1>
21     <div class="condition">
22         <div>
23             {% if arg_dict.article_type_id == 0 %}
24                 <a class="active" href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
25             {% else %}
26                 <a href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
27             {% endif %}
28             {% for i in article_type_list %}
29                 {% if arg_dict.article_type_id == i.id %}
30                     <a class="active" href="/article-{{ i.id }}-{{ arg_dict.category_id }}.html">{{ i.caption }}</a>
31                 {% else %}
32                     <a href="/article-{{ i.id }}-{{ arg_dict.category_id }}.html">{{ i.caption }}</a>
33                 {% endif %}
34             {% endfor %}
35         </div>
36         <div>
37             {% if arg_dict.article_type_id == 0 %}
38                 <a class="active" href="/article-{{ arg_dict.article_type_id }}-0.html">全部</a>
39             {% else %}
40                 <a href="/article-{{ arg_dict.article_type_id }}-0.html">全部</a>
41             {% endif %}
42             {% for i in category_list %}
43                 {% if arg_dict.category_id == i.id %}
44                     <a class="active" href="/article-{{ arg_dict.article_type_id }}-{{ i.id }}.html">{{ i.caption }}</a>
45                 {% else %}
46                     <a href="/article-{{ arg_dict.article_type_id }}-{{ i.id }}.html">{{ i.caption }}</a>
47                 {% endif %}
48             {% endfor %}
49         </div>
50     </div>
51 
52     <h1>查询结果</h1>
53     <ul>
54         {% for i in result %}
55             <li>{{ i.id }}{{ i.title }}</li>
56         {% endfor %}
57     </ul>
58 
59 </body>
60 </html>
html

方法二:自定义simple_tag 知道就行 我tm都用混了

方法三:存到内存里

 models.py

views.py 获取方式

前端使用的时候用

{{ for i in article_type_list }}

{{ i.0 }} {{ i.1 }}获取

...

 1 class Article(models.Model):
 2     title = models.CharField(max_length=32)
 3     content = models.CharField(max_length=255)
 4     category = models.ForeignKey('Category')
 5     # article_type = models.ForeignKey('ArticleType')
 6     type_choice = (
 7             (1,'Python'),
 8             (2,'OpenStack'),
 9             (3,'Linux'),
10         )
11     article_type_id = models.IntegerField(choices=type_choice)
models.py

方法四:

后端反生成url

reverse模块:http://www.cnblogs.com/x54256/p/7784444.html

josnp(跨域ajax请求)

CORS:http://www.cnblogs.com/wupeiqi/articles/5703697.html

(随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,使得浏览器允许跨域请求。。。)

由于浏览器具有同源策略(阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。),所以无法直接用ajax进行跨域请求 

 (<a>,<iframe>,<script>,<img>标签不受同源策略影响)jsonp利用了<script src=...></script>绕开了同源策略

jsonp的本质

 1 a.创建script标签
 2 var tag = document.createElement('script');
 3 
 4 b.src=远程地址
 5 tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list';    # 设置执行函数的名字
 6 
 7 c.添加标签到head下执行,然后快速删除
 8 document.head.appendChild(tag);
 9 document.head.removeChild(tag);
10 
11 d.接收返回的数据(必须是js格式)
12 function list(arg) {
13     console.log(arg);    # 输出返回的值
14 }

原生js

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <input type="button" value="获取数据" onclick="getContent();"/>
 9 </body>
10 <script>
11     function getContent() {
12         var tag = document.createElement('script');
13         tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html';
14         document.head.appendChild(tag);
15         document.head.removeChild(tag);
16     }
17     function list(arg) {
18         console.log(arg);
19     }
20 </script>
21 </html>
原生js

jQuery方式

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <input type="button" value="获取数据" onclick="getContent();"/>
 9 </body>
10 <script src="/static/jquery-1.8.2.js"></script>
11 <script>
12     function getContent() {
13         $.ajax({
14             url: 'http://www.jxntv.cn/data/jmd-jxtv2.html',
15             dataType: 'jsonp',
16             jsonp: 'callback',
17             jsonpCallback: 'list'
18         })
19     }
20     function list(arg) {
21         console.log(arg);
22     }
23 </script>
24 </html>
jQ方式

XSS过滤

beautifulsoup4对标签进行过滤

a.过滤单个标签

 1 content="""
 2 <p class='c1' id='i1'>
 3     asdfaa<span style="font-family:NSimSun;">sdf<a>a</a>sdf</span>sdf
 4 </p>
 5 <p>
 6     <strong class='c2' id='i2'>asdf</strong>
 7     <script>alert(123)</script>
 8 </p>
 9 <h2>
10     asdf
11 </h2>
12 """
13 from bs4 import BeautifulSoup
14 
15 soup = BeautifulSoup(content, 'html.parser')    # 解析器(把字符串解析成一个文档对象)
16 tag = soup.find('script')     # 找到要清除地标签
17 tag.hidden = True       # 是否连标签一起清除
18 tag.clear()             # 清除找到的标签
19 
20 content = soup.decode()     # 将对象解码成字符串
21 print(content)
View Code

b.过滤多个标签

 

 1 content="""
 2 <p class='c1' id='i1'>
 3     asdfaa<span style="font-family:NSimSun;">sdf<a>a</a>sdf</span>sdf
 4 </p>
 5 <p>
 6     <strong class='c2' id='i2'>asdf</strong>
 7     <script>alert(123)</script>
 8 </p>
 9 <h2>
10     asdf
11 </h2>
12 """
13 
14 tags = ['p','strong']   # 白名单 只允许p,strong标签通过
15 from bs4 import BeautifulSoup
16 soup = BeautifulSoup(content, 'html.parser')    # 解析器(把字符串解析成一个文档对象)
17 
18 for tag in soup.find_all():
19     if tag.name in tags:    # 判断当前标签是否在白名单中
20         pass
21     else:
22         tag.hidden = True
23         tag.clear()
24 
25 content = soup.decode()     # 将对象解码成字符串
26 print(content)
View Code

c.过滤标签和标签中的属性

 1 content="""
 2 <p class='c1' id='i1'>
 3     asdfaa<span style="font-family:NSimSun;">sdf<a>a</a>sdf</span>sdf
 4 </p>
 5 <p>
 6     <strong class='c2' id='i2'>asdf</strong>
 7     <script>alert(123)</script>
 8 </p>
 9 <h2>
10     asdf
11 </h2>
12 """
13 tags = {
14     'p': ['class'],
15     'strong': ['id',]
16 }
17 from bs4 import BeautifulSoup
18 soup = BeautifulSoup(content, 'html.parser')
19 
20 for tag in soup.find_all():
21     if tag.name in tags:    # 通过标签的筛选
22         input_attrs = tag.attrs  # 获取当前标签的属性{'class': 'c1', 'id': 'i1'}
23         valid_attrs = tags[tag.name]  # 获取当前标签白名单中的属性['class']
24         print(list(input_attrs.keys()))  # input_attrs.keys()在python3中是迭代器,所以要转换成列表格式['class', 'id']
25         for k in list(input_attrs.keys()):    # 不能再迭代的过程中删除迭代的元素,所以用这种方式
26             if k in valid_attrs:
27                 pass
28             else:        # 如果白名单中不存在直接删除该标签多余的属性
29                 del tag.attrs[k]
30     else:
31         tag.hidden = True
32         tag.clear()
33         continue
34 
35 content = soup.decode()
36 print(content)
View Code

单例模式

永远使用一个对象的实例,节省资源

用处:当创建的对象(对象1,对象2,...)一毛一样时使用

方法一:

 1 class Foo(object):
 2     instance = None     # 一开始为空,第一次使用的时候给他赋值,以后每次使用都调用的是它
 3 
 4     def __init__(self):
 5         self.name = 'alex'
 6 
 7     @classmethod        # 类方法,实际上和所在类一点关系都没有
 8     def get_instance(cls):
 9         if Foo.instance:
10             return Foo.instance
11         else:
12             Foo.instance = Foo()    # 第一次使用的时候实例化 并给instance赋值
13             return Foo.instance
14 
15     def process(self):
16         return '123'
17 
18 # obj1 = Foo()
19 # obj2 = Foo()
20 # print(id(obj1),id(obj2))   # 创建时实例两个对象
21 
22 obj1 = Foo.get_instance()
23 obj2 = Foo.get_instance()
24 print(id(obj1),id(obj2))     # 用的同一个对象 id是一样的
View Code

方法二:***(优点不改变用户使用的方法)

 1 class Foo(object):
 2     instance = None
 3 
 4     def __init__(self):
 5         self.name = 'alex'
 6 
 7     def __new__(cls, *args, **kwargs):
 8         if Foo.instance:
 9             return Foo.instance
10         else:
11              Foo.instance = object.__new__(cls, *args, **kwargs)
12              return Foo.instance
13 
14 obj1 = Foo()
15 obj2 = Foo()
16 print(id(obj1),id(obj2))
View Code

 

posted @ 2017-11-26 20:16  想54256  阅读(347)  评论(0编辑  收藏  举报