Django入门(六)之搜索功能、JSONP实现跨域请求、XSS过滤和单例模式

上一篇文章>Django入门(五)之ModelForm操作、原生Ajax、伪Ajax、文件上传和图片验证码生成

一、本机环境


操作系统:Red Hat Enterprise Linux Server release 7.3 (Maipo)
Python版本:python3.6
Django版本:Django-2.1.5
[root@python _Django]# tree item
item
├── app
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       └── __init__.cpython-36.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-36.pyc
│   │   ├── __init__.cpython-36.pyc
│   │   └── models.cpython-36.pyc
│   ├── tests.py
│   └── views.py
├── item
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── static
│   └── jquery-1.12.4.min.js
└── templates

二、博客搜索功能


1、通过网址完成筛选

(1)配置models.py
[root@python item]# vim app/models.py
from django.db import models
class Category(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(Category, on_delete=models.CASCADE)
    article_type = models.ForeignKey(ArticleType, on_delete=models.CASCADE)
(2)生成数据库表数据
[root@python item]# python manage.py makemigrations
[root@python item]# python manage.py migrate 

Django入门(六)之搜索功能、JSONP实现跨域请求、XSS过滤和单例模式_第1张图片
Django入门(六)之搜索功能、JSONP实现跨域请求、XSS过滤和单例模式_第2张图片
Django入门(六)之搜索功能、JSONP实现跨域请求、XSS过滤和单例模式_第3张图片

(3)配置views.py
[root@python item]# vim app/views.py
from django.shortcuts import render
from app import models
def article(request,*args,**kwargs):
    condition = {}
    for k,v in kwargs.items():
        if v == '0':
            pass
        else:
            condition[k] = v
    article_type_list = models.ArticleType.objects.all()
    category_list = models.Category.objects.all()
    res = models.Article.objects.filter(**condition)

    return render(
        request,
        'article.html',
        {
            'res': res,
            'article_type_list': article_type_list,
            'category_list': category_list,
        }
    )
(4)配置HTML
[root@python item]# vim templates/article.html



    
    
    


    

过滤条件

全部 {% for row in article_type_list %} {{ row.caption }} {% endfor %}
全部 {% for row in category_list %} {{ row.caption }} {% endfor %}

查询结果

    {% for row in res %}
  • {{ row.id }}-{{ row.title }}
  • {% endfor %}
(5)访问并查看结果

我们可以通过修改(0-5)这2个“0”来完成对数据的筛选,“0”代表着所有数据!!!

http://10.10.10.111:8000/article-0-0.html/

Django入门(六)之搜索功能、JSONP实现跨域请求、XSS过滤和单例模式_第4张图片

2、通过过滤条件完成筛选

(1)配置views.py
[root@python item]# vim app/views.py
from django.shortcuts import render
from app import models
def article(request,*args,**kwargs):
    condition = {}
    for k,v in kwargs.items():
        kwargs[k] = int(v)
        if v == "0":
            pass
        else:
            condition[k] = v
    article_type_list = models.ArticleType.objects.all()
    category_list = models.Category.objects.all()
    res = models.Article.objects.filter(**condition)

    return render(
        request,
        'article.html',
        {
            'res': res,
            'article_type_list': article_type_list,
            'category_list': category_list,
            'arg_dict': kwargs,
        }
    )
(2)配置HTML



    
    
    


    

过滤条件

{% if arg_dict.article_type_id == 0 %} 全部 {% else %} 全部 {% endif %} {% for row in article_type_list %} {% if row.id == arg_dict.article_type_id %} {{ row.caption }} {% else %} {{ row.caption }} {% endif %} {% endfor %}
{% if arg_dict.category_id == 0 %} 全部 {% else %} 全部 {% endif %} {% for row in category_list %} {% if row.id == arg_dict.category_id %} {{ row.caption }} {% else %} {{ row.caption }} {% endif %} {% endfor %}

查询结果

    {% for row in res %}
  • {{ row.id }}-{{ row.title }}
  • {% endfor %}
(3)访问并查看结果

我们可以通过过滤条件完成筛选!!!

http://10.10.10.111:8000/article-0-0.html/

Django入门(六)之搜索功能、JSONP实现跨域请求、XSS过滤和单例模式_第5张图片

3、simple_tag方式

(1)配置filter.py
[root@python item]# mkdir app/templatetags/
[root@python item]# vim app/templatetags/filter.py
#!/usr/bin/env python
# coding:utf-8
from django import template
from django.utils.safestring import mark_safe
register = template.Library()

@register.simple_tag
def filter_all(k, arg_dict):
    """
    {% if arg_dict.article_type_id == 0 %}
        全部
    {% else %}
        全部
    {% endif %}
    """
    if k == 'article_type_id':
        n1 = arg_dict['article_type_id']
        n2 = arg_dict['category_id']
        if n1 == 0:
            result = '全部' % (n2)
        else:
            result = '全部' % (n2)
    else:
        n1 = arg_dict['category_id']
        n2 = arg_dict['article_type_id']
        if n1 == 0:
            result = '全部' % (n2)
        else:
            result = '全部' % (n2)
    return mark_safe(result)

@register.simple_tag
def filter_article_type(article_type_list, arg_dict):
    """
    {% for row in article_type_list %}
        {% if row.id == arg_dict.article_type_id %}
            {{ row.caption }}
        {% else %}
            {{ row.caption }}
        {% endif %}
    {% endfor %}
    """
    result = []
    for row in article_type_list:
        if row.id == arg_dict['article_type_id']:
            t = '%s' % (row.id, arg_dict['category_id'], row.caption,)
        else:
            t = '%s' % (row.id, arg_dict['category_id'], row.caption,)
        result.append(t)
    return mark_safe(''.join(result))

@register.simple_tag
def filter_category(category_list, arg_dict):
    """
    {% for row in category_list %}
        {% if row.id == arg_dict.category_id %}
            {{ row.caption }}
        {% else %}
            {{ row.caption }}
        {% endif %}
    {% endfor %}
    """
    result = []
    for row in category_list:
        if row.id == arg_dict['category_id']:
            t = '%s' %(arg_dict["article_type_id"],row.id,row.caption,)
        else:
            t = '%s' %(arg_dict["article_type_id"],row.id,row.caption,)
        result.append(t)
    return mark_safe(''.join(result))
(2)配置HTML
[root@python item]# vim templates/article.html
{% load filter %}



    
    
    


    

过滤条件

{% filter_all 'article_type_id' arg_dict %} {% filter_article_type article_type_list arg_dict %}
{% filter_all 'category_id' arg_dict %} {% filter_category category_list arg_dict %}

查询结果

    {% for row in res %}
  • {{ row.id }}-{{ row.title }}
  • {% endfor %}
(3)访问并查看结果

我们可以发现和之前的结果一样,但是HTML里面更加简洁!!!

http://10.10.10.111:8000/article-0-0.html/

4、内存存储数据

(1)配置models.py
[root@python item]# vim app/models.py
from django.db import models
class Category(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(Category, on_delete=models.CASCADE)
    # article_type = models.ForeignKey(ArticleType, on_delete=models.CASCADE)
    type_choice = (
        (1,'Python'),
        (2,'Linux'),
        (3,'Go'),
        (4,'Java'),
        (5,'运维'),
    )
    article_type_id = models.IntegerField(choices=type_choice)
(2)设置默认值及修改数据库表
[root@python item]# python manage.py makemigrations
You are trying to add a non-nullable field 'article_type_id' to article without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> 1          ###设置默认值为1

[root@python item]# python manage.py migrate       
(3)配置views.py
[root@python item]# vim app/views.py
from django.shortcuts import render
from app import models
def article(request,*args,**kwargs):
    condition = {}
    for k,v in kwargs.items():
        kwargs[k] = int(v)
        if v == "0":
            pass
        else:
            condition[k] = v
    # article_type_list = models.ArticleType.objects.all()
    article_type_list = models.Article.type_choice
    category_list = models.Category.objects.all()
    res = models.Article.objects.filter(**condition)

    return render(
        request,
        'article.html',
        {
            'res': res,
            'article_type_list': article_type_list,
            'category_list': category_list,
            'arg_dict': kwargs,
        }
    )
(4)配置filter.py
[root@python item]# vim app/templatetags/filter.py
#!/usr/bin/env python
# coding:utf-8
from django import template
from django.utils.safestring import mark_safe
register = template.Library()

@register.simple_tag
def filter_all(k, arg_dict):
    """
    {% if arg_dict.article_type_id == 0 %}
        全部
    {% else %}
        全部
    {% endif %}
    """
    if k == 'article_type_id':
        n1 = arg_dict['article_type_id']
        n2 = arg_dict['category_id']
        if n1 == 0:
            result = '全部' % (n2)
        else:
            result = '全部' % (n2)
    else:
        n1 = arg_dict['category_id']
        n2 = arg_dict['article_type_id']
        if n1 == 0:
            result = '全部' % (n2)
        else:
            result = '全部' % (n2)
    return mark_safe(result)


@register.simple_tag
def filter_article_type(article_type_list, arg_dict):
    """
    {% for row in article_type_list %}
        {% if row.id == arg_dict.article_type_id %}
            {{ row.caption }}
        {% else %}
            {{ row.caption }}
        {% endif %}
    {% endfor %}
    """
    result = []
    for row in article_type_list:
        if row[0] == arg_dict['article_type_id']:
            t = '%s' % (row[0], arg_dict['category_id'], row[1],)
        else:
            t = '%s' % (row[0], arg_dict['category_id'], row[1],)
        result.append(t)
    return mark_safe(''.join(result))

@register.simple_tag
def filter_category(category_list, arg_dict):
    """
    {% for row in category_list %}
        {% if row.id == arg_dict.category_id %}
            {{ row.caption }}
        {% else %}
            {{ row.caption }}
        {% endif %}
    {% endfor %}
    """
    result = []
    for row in category_list:
        if row.id == arg_dict['category_id']:
            t = '%s' %(arg_dict["article_type_id"],row.id,row.caption,)
        else:
            t = '%s' %(arg_dict["article_type_id"],row.id,row.caption,)
        result.append(t)
    return mark_safe(''.join(result))
(5)访问并查看结果

我们可以发现和之前的结果一样!!!

http://10.10.10.111:8000/article-0-0.html/

三、JSONP实现跨域请求


1、JSONP介绍

import requests
request.get('http://www.baidu.com')
request.post('http://www.baidu.com')
由于浏览器具有同源策略(阻止Ajax请求,无法阻止)
方法:
	- 创建script标签
	- src=远程地址
	- 返回的数据必须是js格式

注意:JSONP只能发GET请求

2、requests安装

下载地址:https://pypi.org/project/requests/#files

[root@python ~]# wget https://files.pythonhosted.org/packages/52/2c/514e4ac25da2b08ca5a464c50463682126385c4272c18193876e91f4bc38/requests-2.21.0.tar.gz
[root@python ~]# tar xf requests-2.21.0.tar.gz
[root@python ~]# cd requests-2.21.0/
[root@python requests-2.21.0]# python setup.py install

### 测试
[root@python requests-2.21.0]# python
Python 3.6.0 (default, Jan  8 2019, 05:27:57) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests

3、JSONP使用(原生方式)

(1)配置urls.py
[root@python item]# vim item/urls.py
from django.contrib import admin
from django.urls import path
from app import views
from django.urls import re_path
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('article-(?P\d+)-(?P\d+).html/', views.article),
    path('req/', views.req),
]
(2)配置views.py
[root@python item]# vim app/views.py
from django.shortcuts import render
from app import models
def article(request,*args,**kwargs):
    condition = {}
    for k,v in kwargs.items():
        kwargs[k] = int(v)
        if v == "0":
            pass
        else:
            condition[k] = v
    # article_type_list = models.ArticleType.objects.all()
    article_type_list = models.Article.type_choice
    category_list = models.Category.objects.all()
    res = models.Article.objects.filter(**condition)

    return render(
        request,
        'article.html',
        {
            'res': res,
            'article_type_list': article_type_list,
            'category_list': category_list,
            'arg_dict': kwargs,
        }
    )

import requests
def req(request):
    response = requests.get('https://www.apiopen.top/weatherApi?city=成都')
    # print (response.content)  ###字节
    # print (response.text)     ###字符串
    response.encoding = 'utf-8'
    return render(request,'req.html', {'result': response.text})
(3)配置HTML
[root@python item]# vim templates/req.html



    
    


    

后台获取结果

{{ result }}

js直接获取结果

(4)访问并查看结果
http://10.10.10.111:8000/req/

Django入门(六)之搜索功能、JSONP实现跨域请求、XSS过滤和单例模式_第6张图片

4、JSONP使用(jQuery方式)

(1)配置HTML



    
    


    

后台获取结果

{{ result }}

js直接获取结果

(2)访问并查看结果
http://10.10.10.111:8000/req/

四、XSS过滤


1、安装第三方软件

(1)安装beatifulsoup4

通过beatifulsoup4实现过滤!!!
下载地址:https://www.crummy.com/software/BeautifulSoup/bs4/download/4.7/

[root@python ~]# wget https://www.crummy.com/software/BeautifulSoup/bs4/download/4.7/beautifulsoup4-4.7.1.tar.gz
[root@python ~]# tar xf beautifulsoup4-4.7.1.tar.gz
[root@python ~]# cd beautifulsoup4-4.7.1/
[root@python beautifulsoup4-4.7.1]# python setup.py install
(2)报错解决

<1> 报错:

[root@python beautifulsoup4-4.7.1]# python
Python 3.6.0 (default, Jan  8 2019, 05:27:57) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from bs4 import BeautifulSoup
Traceback (most recent call last):
  File "", line 1, in 
  File "/mnt/beautifulsoup4-4.7.1/bs4/__init__.py", line 52
    'You are trying to run the Python 2 version of Beautiful Soup under Python 3. This will not work.'<>'You need to convert the code, either by installing it (`python setup.py install`) or by running 2to3 (`2to3 -w bs4`).'

<2> 解决方法:

python3不再有urllib2,取而代之的是urllib.request,因此把在Python2中使用urllib2的地方全部替代为urllib.request即可!!!

[root@python beautifulsoup4-4.7.1]# 2to3 -w bs4
[root@python beautifulsoup4-4.7.1]# python
Python 3.6.0 (default, Jan  8 2019, 05:27:57) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from bs4 import BeautifulSoup

2、查找script

(1)新建个test.py
[root@python item]# vim test.py
#!/usr/bin/env python
#coding:utf-8
content = """

dream

""" from bs4 import BeautifulSoup soup = BeautifulSoup(content,'html.parser') tag = soup.find('script') print (tag)
(2)查看结果
[root@python item]# python test.py 

3、清空script内容

(1)配置test.py
[root@python item]# vim test.py
#!/usr/bin/env python
#coding:utf-8
content = """

dream

""" from bs4 import BeautifulSoup soup = BeautifulSoup(content,'html.parser') tag = soup.find('script') tag.clear() content = soup.decode() print (content)
(2)查看结果

可以发现script里面的内容被清空了!!!

[root@python item]# python test.py 

dream

4、清除script标签及内容

(1)配置test.py
[root@python item]# vim test.py
#!/usr/bin/env python
#coding:utf-8
content = """

dream

""" from bs4 import BeautifulSoup soup = BeautifulSoup(content,'html.parser') tag = soup.find('script') tag.hidden = True tag.clear() content = soup.decode() print (content)
(2)查看结果
[root@python item]# python test.py 

dream

5、清除标签属性

(1)配置test.py
[root@python item]# vim test.py
#!/usr/bin/env python
#coding:utf-8
content = """

dreamdreamya

""" from bs4 import BeautifulSoup soup = BeautifulSoup(content,'html.parser') tag = soup.find('script') tag.hidden = True tag.clear() span = soup.find('span') del(span.attrs['style']) content = soup.decode() print (content)
(2)查看结果
[root@python item]# python test.py 

dreamdreamya

6、通过标签白名单过滤

(1)配置test.py
[root@python item]# vim test.py
#!/usr/bin/env python
#coding:utf-8
content = """

dreamdreamya

1111

231

""" tags = ['p','div'] from bs4 import BeautifulSoup soup = BeautifulSoup(content,'html.parser') for tag in soup.find_all(): if tag.name not in tags: tag.hidden = True tag.clear() content = soup.decode() print (content)
(2)查看结果
[root@python item]# python test.py 

dream

1111

231

7、通过标签白名单及属性过滤

(1)配置test.py
[root@python item]# vim test.py
#!/usr/bin/env python
#coding:utf-8
content = """

dreamdreamya

1111

ccc

iii

231

""" tags = { 'p': ['class'], 'div': ['id'], } from bs4 import BeautifulSoup soup = BeautifulSoup(content,'html.parser') for tag in soup.find_all(): if tag.name not in tags: tag.hidden = True tag.clear() continue ### 用户提交标签的所有属性,字典 input_attrs = tag.attrs valid_attrs = tags[tag.name] for k in list(input_attrs.keys()): if k not in valid_attrs: del(tag.attrs[k]) content = soup.decode() print (content)
(2)查看结果
[root@python item]# python test.py 

dream

1111

ccc

iii

231

五、单列模式


1、方式一

(1)配置singleton.py
[root@python item]# vim singleton.py
#!/usr/bin/env python
#coding:utf-8
class SingletonPattern(object):
    instance = None
    def __init__(self):
        self.name = 'dream'

    @classmethod
    def get_instance(cls):
        if SingletonPattern.instance:
            return SingletonPattern.instance
        else:
            SingletonPattern.instance = SingletonPattern()
            return SingletonPattern.instance
    def process(self):
        return "dreamya"

obj1 = SingletonPattern.get_instance()
obj2 = SingletonPattern.get_instance()
print (id(obj1),id(obj2))
(2)查看结果
[root@python item]# python singleton.py 
140114680407936 140114680407936

2、方式二

基于new方法实现!!!

[root@python item]# vim singleton.py
#!/usr/bin/env python
#coding:utf-8
class SingletonPattern(object):
    instance = None
    def __init__(self):
        self.name = 'dream'
    def __new__(cls, *args, **kwargs):
        if SingletonPattern.instance:
            return SingletonPattern.instance
        else:
            SingletonPattern.instance = object.__new__(cls, *args, **kwargs)
            return SingletonPattern.instance

obj1 = SingletonPattern()
obj2 = SingletonPattern()
print (id(obj1),id(obj2))
(2)查看结果
[root@python item]# python singleton.py 
140203612212864 140203612212864

你可能感兴趣的:(Django)