第八章(6)

  1. modelform
  2. 原生ajax
  3. 上传文件,XMLHttpRequest,jquery,iframe 
  4. XMLHttpRequest,jquery,iframe 应用场景
  5. 图片验证码 + session
  6. KindEdittor博客插件
  7. 前端组合搜索
  8. jsonp
  9. xss过滤

1,modelform

ModelForm
    a.  class Meta:
            model,                           # 对应Model的
            fields=None,                     # 字段
            exclude=None,                    # 排除字段
            labels=None,                     # 提示信息
            help_texts=None,                 # 帮助提示信息
            widgets=None,                    # 自定义插件
            error_messages=None,             # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
            field_classes=None               # 自定义字段类 (也可以自定义字段)
            localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
            如:
                数据库中
                    2016-12-27 04:10:57
                setting中的配置
                    TIME_ZONE = 'Asia/Shanghai'
                    USE_TZ = True
                则显示:
                    2016-12-27 12:10:57
    b. 验证执行过程
        is_valid -> full_clean -> 钩子 -> 整体错误
 
    c. 字典字段验证
        def clean_字段名(self):
            # 可以抛出异常
            # from django.core.exceptions import ValidationError
            return "新值"
    d. 用于验证
        model_form_obj = XXOOModelForm()
        model_form_obj.is_valid()
        model_form_obj.errors.as_json()
        model_form_obj.clean()
        model_form_obj.cleaned_data
    e. 用于创建
        model_form_obj = XXOOModelForm(request.POST)
        #### 页面显示,并提交 #####
        # 默认保存多对多
            obj = form.save(commit=True)
        # 不做任何操作,内部定义 save_m2m(用于保存多对多)
            obj = form.save(commit=False)
            obj.save()      # 保存单表信息
            obj.save_m2m()  # 保存关联多对多信息
 
    f. 用于更新和初始化
        obj = model.tb.objects.get(id=1)
        model_form_obj = XXOOModelForm(request.POST,instance=obj)
        ...
 
        PS: 单纯初始化
            model_form_obj = XXOOModelForm(initial={...})
            
            http://www.cnblogs.com/wupeiqi/articles/6229414.html

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from app01 import views
urlpatterns = [
    #path('admin/', admin.site.urls),
    url(r'^index/',views.index),
    url(r'^user_list/',views.user_list),
    url(r'^edit-(\d+)',views.user_edit)
]

models.py

from django.db import models

# Create your models here.

class UserType(models.Model):
    caption = models.CharField(max_length=32)

    def __str__(self):
        return self.caption


class UserGroup(models.Model):
    name = models.CharField(max_length=32)

    def __str__(self):
        return self.name



class UserInfo(models.Model):
    username = models.CharField(max_length=32)
    email = models.EmailField()
    user_type = models.ForeignKey(to='UserType',to_field='id',on_delete=models.CASCADE)
    u2g = models.ManyToManyField(UserGroup)

    def __unicode__(self):
        return self.username,self.email

views.py

from django.shortcuts import render,HttpResponse
from app01 import models

from django import forms
from django.forms import fields as Ffields
from django.forms import widgets as Fwidgets
class UserInfoModelForm(forms.ModelForm):

    is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())

    class Meta:
        model = models.UserInfo
        fields = '__all__'
        # fields =  ['username','email']
        # exclude = ['username']
        labels = {
            'username': '用户名',
            'email': '邮箱',
            'u2g' : '用户组',
            'user_type' : '用户类型'
        }
        help_texts = {
            'username': '帮助'
        }
        widgets = {
            'username': Fwidgets.Textarea(attrs={'class': 'c1'})
        }
        error_messages = {
            '__all__':{

            },
            'email': {
                'required': '邮箱不能为空',
                'invalid': '邮箱格式错误..',
            }
        }
        field_classes = {
            # 'email': Ffields.URLField
        }

        # localized_fields=('ctime',)

    def clean_username(self):
        old = self.cleaned_data['username']
        return old

# class UserInfoForm(forms.Form):
#     username = Ffields.CharField(max_length=32)
#     email = Ffields.EmailField()
#     user_type = Ffields.ChoiceField(
#         choices=models.UserType.objects.values_list('id','caption')
#     )
#
#     def __init__(self, *args, **kwargs):
#         super(UserInfoForm,self).__init__(*args, **kwargs)
#         self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')


def index(request):
    if request.method == "GET":
        obj = UserInfoModelForm()
        return render(request,'index.html',{'obj': obj})
    elif request.method == "POST":
        obj = UserInfoModelForm(request.POST)
        if obj.is_valid():
            #全部保存
            # obj.save()
            #分开保存
            instance = obj.save(False)
            #报错当前表
            instance.save()
            #保存多对多
            obj.save_m2m()


        # print(obj.is_valid())
        # print(obj.cleaned_data)
        # print(obj.errors.as_json())
        return render(request,'index.html',{'obj': obj})


def user_list(request):
    li = models.UserInfo.objects.all().select_related('user_type')
    return render(request,'user_list.html',{'li': li})

def user_edit(request, nid):
    # 获取当前id对象的用户信息
    # 显示用户已经存在数据
    if request.method == "GET":
        user_obj = models.UserInfo.objects.filter(id=nid).first()
        mf = UserInfoModelForm(instance=user_obj)
        return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
    elif request.method == 'POST':
        user_obj = models.UserInfo.objects.filter(id=nid).first()
        mf = UserInfoModelForm(request.POST,instance=user_obj)
        if mf.is_valid():

            mf.save()
        else:
            print(mf.errors.as_json())
        return render(request,'user_edit.html',{'mf': mf, 'nid': nid})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/index/" method="POST">
        {% csrf_token %}
        {{ obj.as_p }}
        <input type="submit" value="提交"/>
    </form>
</body>
</html>

user_edit.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="POST" action="/edit-{{ nid }}">
        {% csrf_token %}
    {{ mf.as_p }}
        <input type="submit" value="提交"/>
    </form>
</body>
</html>

user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
       <ul>
           {% for row in li %}
               <li>{{ row.username }} - {{ row.user_type.caption }} - <a href="/edit-{{ row.id }}/">编辑</a></li>
           {% endfor %}
       </ul>
</body>
</html>

modelsfrom验证过程

1,models字段正则表达式验证
2,models验证通过返回is_valid()
2,错误验证过程(errors.as_data)	
	2.1 error下的self.full_clean()
	2.2 def full_clean(self):
	2.3 
		 self._clean_fields()
          self._clean_form()
          self._post_clean()
           def clean(self):

  

2,原生ajax

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

1、XmlHttpRequest对象介绍 

    XmlHttpRequest对象的主要方法: 
a. void open(String method,String url,Boolen async)
   用于创建请求
    
   参数:
       method: 请求方式(字符串类型),如:POST、GET、DELETE...
       url:    要请求的地址(字符串类型)
       async:  是否异步(布尔类型)
 
b. void send(String body)
    用于发送请求
 
    参数:
        body: 要发送的数据(字符串类型)
 
c. void setRequestHeader(String header,String value)
    用于设置请求头
 
    参数:
        header: 请求头的key(字符串类型)
        vlaue:  请求头的value(字符串类型)
 
d. String getAllResponseHeaders()
    获取所有响应头
 
    返回值:
        响应头数据(字符串类型)
 
e. String getResponseHeader(String header)
    获取响应头中指定header的值
 
    参数:
        header: 响应头的key(字符串类型)
 
    返回值:
        响应头中指定的header对应的值
 
f. void abort()
 
    终止请求

XmlHttpRequest对象的主要属性:

a. Number readyState
   状态值(整数)
 
   详细:
      0-未初始化,尚未调用open()方法;
      1-启动,调用了open()方法,未调用send()方法;
      2-发送,已经调用了send()方法,未接收到响应;
      3-接收,已经接收到部分响应数据;
      4-完成,已经接收到全部响应数据;
 
b. Function onreadystatechange
   当readyState的值改变时自动触发执行其对应的函数(回调函数)
 
c. String responseText
   服务器返回的数据(字符串类型)
 
d. XmlDocument responseXML
   服务器返回的数据(Xml对象)
 
e. Number states
   状态码(整数),如:200、404...
 
f. String statesText
   状态文本(字符串),如:OK、NotFound...

views.py

def ajax(request):
    return render(request, 'ajax.html')

ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <input type="text"/>
    <input type="button" value="Ajax1" onclick="Ajax1();" />


    <!--
    <input type="text" id="url" />
    <input type="button" value="发送Iframe请求" onclick="iframeRequest();" />
    <iframe id="ifm" src="http://www.baidu.com"></iframe>
    -->

    <form action="/ajax_json/" method="POST" target="ifm1">
        <iframe id="ifm1" name="ifm1" ></iframe>
        <input type="text" name="username" />
        <input type="text" name="email" />
        <input type="submit" onclick="sumitForm();" value="Form提交"/>
    </form>



    <script type="text/javascript" src="/static/jquery-1.12.4.js"></script>
    <script>
        #判断客户端是IE或谷歌
        function getXHR(){
            var xhr = null;
            if(XMLHttpRequest){
                xhr = new XMLHttpRequest();
            }else{
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            return xhr;

        }

        function Ajax1(){
            var xhr = getXHR();
            //var xhr = new XMLHttpRequest();
            xhr.open('POST', '/ajax_json/',true);
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    // 接收完毕
                    var obj = JSON.parse(xhr.responseText);
                    console.log(obj);
                }
            };
            #可以用来发送csrf
            xhr.setRequestHeader('k1','v1');
            #设置送法格式
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            xhr.send("name=root;pwd=123");
        }

        /*
        function iframeRequest(){
            var url = $('#url').val();
            $('#ifm').attr('src',url);
        }
        */


        function sumitForm(){
            $('#ifm1').load(function(){
                var text = $('#ifm1').contents().find('body').text();
                var obj = JSON.parse(text);
            })
        }

    </script>
</body>
</html>

4,上传文件,XMLHttpRequest,jquery,iframe 

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from app01 import views
urlpatterns = [
    #path('admin/', admin.site.urls),
    url(r'^index/',views.index),
    url(r'^user_list/',views.user_list),
    url(r'^edit-(\d+)',views.user_edit),
    url(r'^ajax/',views.ajax),
    url(r'^ajax_json/$',views.ajax_json),
    url(r'^upload/$',views.upload),
    url(r'^upload_file/$', views.upload_file),

]

views.py

def upload(request):
    return render(request,'upload.html')

def upload_file(request):
    username = request.POST.get('username')
    fafafa = request.FILES.get('fafafa')
    import os
    img_path = os.path.join('static/imgs/',fafafa.name)
    with open(img_path,'wb') as f:
        for item in fafafa.chunks():
            f.write(item)
    ret = {'code': True,'data': img_path}
    import json
    return HttpResponse(json.dumps(ret))

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .upload{
            display: inline-block;padding: 10px;
            background-color: brown;
            position: absolute;
            top: 0;
            right: 0;
            left: 0;
            z-index: 90;
        }
        .file{
            width: 100px;height: 50px;opacity: 0;
            position: absolute;
            top:0;
            right:0;
            left:0;
            z-index:100;
        }
    </style>
</head>
<body>
    <div style="position: relative;width: 100px;height: 50px;">
        <input class="file" type="file"  id="fafafa" name="afafaf"/>
        <a class="upload">上传</a>
    </div>
    <input type="button" value="提交XHR" onclick="xhrsbmit();"/>
    <input type="button" value="提交jQuery" onclick="jqsubmit();"/>
    <hr/>

    <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1">
        <iframe id="ifm1" name="ifm1" style="display: none;"></iframe>
        <input type="file" name="fafafa" onclick="changeUpload();"/>
        <input type="submit" onclick="iframesubmit();" value="Form提交"/>
    </form>
    <div id="preview"></div>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
    
        #原生ajax上传   
        function xhrsbmit(){
            //$('#fa')[0]
            var file_obj = document.getElementById('fafafa').files[0];

            var fd = new FormData();
            fd.append('username','root');
            fd.append('fafafa',file_obj);

            var xhr = new XMLHttpRequest();
            xhr.open('POST','/upload_file/',true);
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    //接收完毕
                    var obj = JSON.parse(xhr.responseText);
                    console.log(obj);
                }
            };
            xhr.send(fd);
        }
        
        #ajax上传
        function jqsubmit(){
            var file_obj = document.getElementById('fafafa').files[0];

            var fd = new FormData();
            fd.append('username','root');
            fd.append('fafafa',file_obj);

            $.ajax({
                url: '/upload_file/',
                type:'POST',
                data:fd,
                processData: false,
                contentType: false,
                success:function(arg,a1,a2){
                    console.log(arg);
                    console.log(a1);
                    console.log(a2);
                }
            })
        }
        
        #iframe上传1
        function changeUpload(){
            $('#ifm1').load(function(){
                var text = $('#ifm1').contents().find('body').text();
                var obj = JSON.parse(text);

                $('#preview').empty();
                var imgTag = document.createElement('img');
                imgTag.src = '/' + obj.data;
                $('#preview').append(imgTag);
            });
            $('#form1').submit();
        }
        
        #iframe上传2
        function iframesubmit(){
            $('#ifm1').load(function(){
                var text = $('#ifm1').contents().find('body').text();
                var obj = JSON.parse(text);

                $('#preview').empty();
                var imgTag = document.createElement('img');
                imgTag.src = '/' + obj.data;
                $('#preview').append(imgTag);
            })
        }
    </script>
</body>
</html>

4,原生jquery,jquery,iframe应用场景

如果发送的是普通数--> 1,jquery 2,XMLHttpRequest 3,iframe
如果是文件 ----> 1,iframe 2,XMLHttpRequest(ajax和原生)

5,图片验证码 + session

1,session
2,check_code.py(依赖:Pillow,字体文件)
3,src属性后面加 (刷新)
 <div class="col-xs-5">
                    <img src="/check_code.html" onclick="changeCheckCode(this);">
                    <!-- <img src="/static/imgs/avatar/20130809170025.png"> -->
                </div>
            </div>

        </div>
        <div class="checkbox">
            <label>
                <input type="checkbox"> 一个月内自动登陆
            </label>
            <div class="right">
                <a href="#">忘记密码?</a>
            </div>
        </div>
        <button type="submit" class="btn btn-default">登 陆</button>
    </form>
</div>
    <script>
        function changeCheckCode(ths){
            ths.src = ths.src +  '?';

        }
    </script>
</body>
</html>

urls.py

urlpatterns = [
    url(r'^check_code.html$', account.check_code),
]

views.py

from utils.check_code import create_validate_code

def check_code(request):
    """
    验证码
    :param request:
    :return:
    """
    # stream = BytesIO()
    # img, code = create_validate_code()
    # img.save(stream, 'PNG')
    # request.session['CheckCode'] = code
    # return HttpResponse(stream.getvalue())

    # data = open('static/imgs/avatar/20130809170025.png','rb').read()
    # return HttpResponse(data)

    # 1. 创建一张图片 pip3 install Pillow
    # 2. 在图片中写入随机字符串
    # obj = object()
    # 3. 将图片写入到制定文件
    # 4. 打开制定目录文件,读取内容
    # 5. HttpResponse(data)

    stream = BytesIO()
    img, code = create_validate_code()
    img.save(stream,'PNG')
    request.session['CheckCode'] = code
    return HttpResponse(stream.getvalue())

check_code.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter

_letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper()  # 大写字母
_numbers = ''.join(map(str, range(3, 10)))  # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers))


def create_validate_code(size=(120, 30),
                         chars=init_chars,
                         img_type="GIF",
                         mode="RGB",
                         bg_color=(255, 255, 255),
                         fg_color=(0, 0, 255),
                         font_size=18,
                         font_type="Monaco.ttf",
                         length=4,
                         draw_lines=True,
                         n_line=(1, 2),
                         draw_points=True,
                         point_chance=2):
    """
    @todo: 生成验证码图片
    @param size: 图片的大小,格式(宽,高),默认为(120, 30)
    @param chars: 允许的字符集合,格式字符串
    @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
    @param mode: 图片模式,默认为RGB
    @param bg_color: 背景颜色,默认为白色
    @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
    @param font_size: 验证码字体大小
    @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
    @param length: 验证码字符个数
    @param draw_lines: 是否划干扰线
    @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
    @param draw_points: 是否画干扰点
    @param point_chance: 干扰点出现的概率,大小范围[0, 100]
    @return: [0]: PIL Image实例
    @return: [1]: 验证码图片中的字符串
    """

    width, height = size  # 宽高
    # 创建图形
    img = Image.new(mode, size, bg_color)
    draw = ImageDraw.Draw(img)  # 创建画笔

    def get_chars():
        """生成给定长度的字符串,返回列表格式"""
        return random.sample(chars, length)

    def create_lines():
        """绘制干扰线"""
        line_num = random.randint(*n_line)  # 干扰线条数

        for i in range(line_num):
            # 起始点
            begin = (random.randint(0, size[0]), random.randint(0, size[1]))
            # 结束点
            end = (random.randint(0, size[0]), random.randint(0, size[1]))
            draw.line([begin, end], fill=(0, 0, 0))

    def create_points():
        """绘制干扰点"""
        chance = min(100, max(0, int(point_chance)))  # 大小限制在[0, 100]

        for w in range(width):
            for h in range(height):
                tmp = random.randint(0, 100)
                if tmp > 100 - chance:
                    draw.point((w, h), fill=(0, 0, 0))

    def create_strs():
        """绘制验证码字符"""
        c_chars = get_chars()
        strs = ' %s ' % ' '.join(c_chars)  # 每个字符前后以空格隔开

        font = ImageFont.truetype(font_type, font_size)
        font_width, font_height = font.getsize(strs)

        draw.text(((width - font_width) / 3, (height - font_height) / 3),
                  strs, font=font, fill=fg_color)

        return ''.join(c_chars)

    if draw_lines:
        create_lines()
    if draw_points:
        create_points()
    strs = create_strs()

    # 图形扭曲参数
    params = [1 - float(random.randint(1, 2)) / 100,
              0,
              0,
              0,
              1 - float(random.randint(1, 10)) / 100,
              float(random.randint(1, 2)) / 500,
              0.001,
              float(random.randint(1, 2)) / 500
              ]
    img = img.transform(size, Image.PERSPECTIVE, params)  # 创建扭曲

    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)  # 滤镜,边界加强(阈值更大)

    return img, strs

 

6,KindEdittor博客插件

上传文件

urlpatterns = [
    url(r'^upload/$', views.upload),
    url(r'^upload_file/$', views.upload_file),
    url(r'^kind/$', views.kind),
    url(r'^upload_img/$', views.upload_img),
    url(r'^file_manager/$', views.file_manager),
]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<form>
    {% csrf_token %}
    <div style="width: 500px;margin: 0 auto">
        <textarea id="content"></textarea>
    </div>
    <input type="submit" value="提交"/>
</form>

<script src="/static/jquery-1.12.4.js"></script>
<script src="/static/kindeditor-4.1.10/kindeditor-all.js"></script>
\
<script>
    $(function () {

        KindEditor.create('#content', {
            {#                items: ['superscript', 'clearhtml', 'quickformat', 'selectall']#}
            {#                noDisableItems: ["source", "fullscreen"],#}
            {#                designMode: false#}
            #上传文件目录
            uploadJson: '/upload_img/',
            #提交空间管理url
            fileManagerJson: '/file_manager/',
            allowImageRemote: true,
            allowImageUpload: true,
            allowFileManager: true,
            extraFileUploadParams: {
                csrfmiddlewaretoken: "{{ csrf_token }}"
            },
            #设置提交文件名
            filePostName: 'fafafa'

        });


    })
</script>

</body>
</html>
def upload(request):
    return render(request,'upload.html')


def kind(request):
    return render(request, 'kind.html')
    
#上传文件
def upload_img(request):
    #dir可以用来判断是文件或图片
    request.GET.get('dir')
    print(request.FILES.get('fafafa'))
    # 获取文件保存
    import json
    dic = {
        'error': 0,
        'url': '/static/imgs/20130809170025.png',
        'message': '错误了...'
    }

    return HttpResponse(json.dumps(dic))
import os
import time
import json

#文件空间管理
def file_manager(request):
    """
    文件管理
    :param request:
    :return:
    {
        moveup_dir_path:
        current_dir_path:
        current_url:
        file_list: [
            {
                'is_dir': True,
                'has_file': True,
                'filesize': 0,
                'dir_path': '',
                'is_photo': False,
                'filetype': '',
                'filename': xxx.png,
                'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
            },
            {
                'is_dir': True,
                'has_file': True,
                'filesize': 0,
                'dir_path': '',
                'is_photo': False,
                'filetype': '',
                'filename': xxx.png,
                'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
            }
        ]

    }
    """
    
    
    dic = {}
    root_path = 'C:/Users/Administrator/PycharmProjects/day24/static/'
    static_root_path = '/static/'
    request_path = request.GET.get('path')
    if request_path:
        #上传文件目录
        abs_current_dir_path = os.path.join(root_path, request_path)
        #去掉 /
        move_up_dir_path = os.path.dirname(request_path.rstrip('/'))
        dic['moveup_dir_path'] = move_up_dir_path + '/' if move_up_dir_path else move_up_dir_path

    else:
        abs_current_dir_path = root_path
        dic['moveup_dir_path'] = ''

    dic['current_dir_path'] = request_path
    dic['current_url'] = os.path.join(static_root_path, request_path)

    file_list = []
    for item in os.listdir(abs_current_dir_path):
        abs_item_path = os.path.join(abs_current_dir_path, item)
        a, exts = os.path.splitext(item)
        is_dir = os.path.isdir(abs_item_path)
        #判断是文件或目录
        if is_dir:
            temp = {
                'is_dir': True,
                'has_file': True,
                'filesize': 0,
                'dir_path': '',
                'is_photo': False,
                'filetype': '',
                'filename': item,
                'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
            }
        else:
            temp = {
                'is_dir': False,
                'has_file': False,
                'filesize': os.stat(abs_item_path).st_size,
                'dir_path': '',
                'is_photo': True if exts.lower() in ['.jpg', '.png', '.jpeg'] else False,
                'filetype': exts.lower().strip('.'),
                'filename': item,
                'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
            }

        file_list.append(temp)
    dic['file_list'] = file_list
    return HttpResponse(json.dumps(dic))

http://www.cnblogs.com/wupeiqi/articles/6307554.html

7,前端组合搜索

 1 from django.contrib import admin
 2 from django.urls import path
 3 from django.conf.urls import url
 4 from app import views
 5 
 6 urlpatterns = [
 7     #path('admin/', admin.site.urls),
 8     url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html',views.article,name='article'),
 9 
10 ]
url.py
 1 from django.db import models
 2 
 3 # Create your models here.
 4 
 5 class Category(models.Model):
 6     caption = models.CharField(max_length=16)
 7 
 8 class ArticleType(models.Model):
 9     caption = models.CharField(max_length=16)
10 
11 class Article(models.Model):
12     title = models.CharField(max_length=32)
13     content = models.CharField(max_length=255)
14 
15     category = models.ForeignKey(Category,on_delete=models.CASCADE)
16     article_type = models.ForeignKey(ArticleType,on_delete=models.CASCADE)
models.py
 1 from django.shortcuts import render
 2 from app import models
 3 # Create your views here.
 4 
 5 def article(request,*args,**kwargs):
 6     print(kwargs)
 7     condition = {}
 8     for k,v in kwargs.items():
 9         kwargs[k] = int(v)
10         if v == '0':
11             pass
12         else:
13             condition[k] = v
14 
15     article_type_list = models.ArticleType.objects.all()
16     category_list = models.Category.objects.all()
17     result = models.Article.objects.filter(**condition)
18     return render(
19         request,'article.html',{'result':result,
20                                 'article_type_list':article_type_list,
21                                 'category':category_list,
22                                 'arg_dict': kwargs,
23                                 }
24     )
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             border: 1px solid #dddddd;
11             margin: 5px;
12         }
13         .condition a.active{
14             background-color: brown;
15         }
16     </style>
17 </head>
18 <body>
19 <h1>过滤条件</h1>
20 <div class="condition">
21     {% if arg_dict.article_type_id == 0 %}
22         <a class="active" href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
23     {% else %}
24         <a href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
25     {% endif %}
26     {% for row in article_type_list %}
27         {% if row.id == arg_dict.article_type_id %}
28             <a class="active" href="/article-{{ row.id }}-{{ arg_dict.category_id }}.html">{{ row.caption }}</a>
29         {% else %}
30              <a  href="/article-{{ row.id }}-{{ arg_dict.category_id }}.html">{{ row.caption }}</a>
31         {% endif %}
32     {% endfor %}
33 </div>
34 
35 <div class="condition">
36     {% if arg_dict.category_id == 0 %}
37         <a class="active" href="/article-{{ arg_dict.article_type_id }}-0.html">全部</a>
38     {% else %}
39         <a  href="/article-{{ arg_dict.article_type_id }}-0.html">全部</a>
40     {% endif %}
41     {% for row in category %}
42         {% if row.id == arg_dict.category_id  %}
43             <a class="active" href="/article-{{ arg_dict.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
44         {% else %}
45             <a href="/article-{{ arg_dict.article_type_id }}-{{ row.id }}.html">{{ row.caption }}</a>
46         {% endif %}
47     {% endfor %}
48 </div>
49 <h1>查询结果</h1>
50 {% for row in result %}
51     <li>{{ row.id }}-{{ row.title }}-{{ row.content }}</li>
52 {% endfor %}
53 </body>
54 </html>
article.html

优化版

 1 from django.db import models
 2 
 3 # Create your models here.
 4 
 5 class Category(models.Model):
 6     caption = models.CharField(max_length=16)
 7 
 8 # class ArticleType(models.Model):
 9 #     caption = models.CharField(max_length=16)
10 
11 class Article(models.Model):
12     title = models.CharField(max_length=32)
13     content = models.CharField(max_length=255)
14 
15     category = models.ForeignKey(Category)
16     # article_type = models.ForeignKey(ArticleType)
17 
18     type_choice = (
19         (1,'Python'),
20         (2,'OpenStack'),
21         (3,'Linux'),
22     )
23     article_type_id = models.IntegerField(choices=type_choice)
models.py
 1 from django.shortcuts import render
 2 from app01 import models
 3 
 4 def article(request,*args,**kwargs):
 5     print(kwargs)
 6     # print(request.path_info) # 获取当前URL
 7     # from django.urls import reverse
 8     # # {'article_type_id': '0', 'category_id': '0'}
 9     # url = reverse('article',kwargs={'article_type_id': '1', 'category_id': '0'})
10     # print(url)
11     # print(kwargs) # {'article_type_id': '0', 'category_id': '0'}
12     condition = {}
13     for k,v in kwargs.items():
14         kwargs[k] = int(v)
15         if v == '0':
16             pass
17         else:
18             condition[k] = v
19 
20     # article_type_list = models.ArticleType.objects.all()
21     article_type_list = models.Article.type_choice
22     category_list = models.Category.objects.all()
23     result = models.Article.objects.filter(**condition)
24     return  render(
25         request,
26         'article.html',
27         {
28             'result': result,
29             'article_type_list': article_type_list,
30             'category_list': category_list,
31             'arg_dict': kwargs
32         }
33     )
views.py
 1 from django import template
 2 from django.utils.safestring import mark_safe
 3 register = template.Library()
 4 
 5 @register.simple_tag
 6 def filter_all(arg_dict,k):
 7     """
 8     {% if arg_dict.article_type_id == 0 %}
 9         <a class="active" href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
10     {% else %}
11         <a  href="/article-0-{{ arg_dict.category_id }}.html">全部</a>
12     {% endif %}
13     :return:
14     """
15     if k == 'article_type_id':
16         n1 = arg_dict['article_type_id']
17         n2 = arg_dict['category_id']
18         if n1 == 0:
19             ret = '<a class="active" href="/article-0-%s.html">全部</a>' % n2
20         else:
21             ret = '<a href="/article-0-%s.html">全部</a>' % n2
22     else:
23         n1 = arg_dict['category_id']
24         n2 = arg_dict['article_type_id']
25         if n1 == 0:
26             ret = '<a class="active" href="/article-%s-0.html">全部</a>' % n2
27         else:
28             ret = '<a href="/article-%s-0.html">全部</a>' % n2
29 
30     return mark_safe(ret)
31 
32 @register.simple_tag
33 def filter_article_type(article_type_list,arg_dict):
34     """
35     {% for row in article_type_list %}
36         {% if row.id == arg_dict.article_type_id %}
37 
38         {% else %}
39             <a  href="/article-{{ row.id  }}-{{ arg_dict.category_id }}.html">{{ row.caption }}</a>
40         {% endif %}
41     {% endfor %}
42     :return:
43     """
44     ret = []
45     for row in article_type_list:
46         if row[0] == arg_dict['article_type_id']:
47             temp = '<a class="active" href="/article-%s-%s.html">%s</a>' %(row[0],arg_dict['category_id'],row[1],)
48         else:
49             temp = '<a href="/article-%s-%s.html">%s</a>' %(row[0],arg_dict['category_id'],row[1],)
50         ret.append(temp)
51     return mark_safe(''.join(ret))
templatetags/filter.py
 1 {% load filter %}
 2 <!DOCTYPE html>
 3 <html lang="en">
 4 <head>
 5     <meta charset="UTF-8">
 6     <title></title>
 7     <style>
 8         .condition a{
 9             display: inline-block;
10             padding: 3px 5px;
11             border: 1px solid #dddddd;
12             margin: 5px ;
13         }
14         .condition a.active{
15             background-color: brown;
16         }
17     </style>
18 </head>
19 <body>
20     <h1>过滤条件</h1>
21     <div class="condition">
22         <div>
23             {% filter_all arg_dict 'article_type_id' %}
24             {% filter_article_type article_type_list arg_dict %}
25         </div>
26 
27         <div>
28             {% filter_all arg_dict 'category_id' %}
29             {% for row in category_list %}
30                 {% if row.id == arg_dict.category_id %}
31                     <a class="active" href="/article-{{ arg_dict.article_type_id }}-{{ row.id  }}.html">{{ row.caption }}</a>
32                 {% else %}
33                     <a href="/article-{{ arg_dict.article_type_id }}-{{ row.id  }}.html">{{ row.caption }}</a>
34                 {% endif %}
35             {% endfor %}
36         </div>
37     </div>
38     <h1>查询结果</h1>
39     <ul>
40         {% for row in result %}
41             <li>{{ row.id }}-{{ row.title }}</li>
42         {% endfor %}
43     </ul>
44 </body>
45 </html>
article.html

8,jsonp

由于浏览器具有同源策略(阻止Ajax请求,无法阻止<script src='......'><script>)

巧妙:

         - 创建scrIpt 标签

         - src=远程地址

         - 返回的数据必须是js格式

只能发GET请求

jsonp(JSONP跨域请求jQuery方式)

1 from app import views
2 
3 urlpatterns = [
4     #path('admin/', admin.site.urls),
5     url(r'^article-(?P<article_type_id>\d+)-(?P<category_id>\d+).html',views.article,name='article'),
6     url(r'^req/',views.req),
7 
8 ]
urls.py
 1 from django.db import models
 2 
 3 # Create your models here.
 4 
 5 class Category(models.Model):
 6     caption = models.CharField(max_length=16)
 7 
 8 class ArticleType(models.Model):
 9     caption = models.CharField(max_length=16)
10 
11 class Article(models.Model):
12     title = models.CharField(max_length=32)
13     content = models.CharField(max_length=255)
14 
15     category = models.ForeignKey(Category,on_delete=models.CASCADE)
16     article_type = models.ForeignKey(ArticleType,on_delete=models.CASCADE)
models.py
 1 from django.shortcuts import render
 2 from app import models
 3 # Create your views here.
 4 import requests
 5 def article(request,*args,**kwargs):
 6     print(kwargs)
 7     condition = {}
 8     for k,v in kwargs.items():
 9         kwargs[k] = int(v)
10         if v == '0':
11             pass
12         else:
13             condition[k] = v
14 
15     article_type_list = models.ArticleType.objects.all()
16     category_list = models.Category.objects.all()
17     result = models.Article.objects.filter(**condition)
18     return render(
19         request,'article.html',{'result':result,
20                                 'article_type_list':article_type_list,
21                                 'category':category_list,
22                                 'arg_dict': kwargs,
23                                 }
24     )
25 
26 def req(request):
27     response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301')
28     response.encoding = 'utf-8'
29     return render(request,'req.html',{'result': respo
views.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <h1>后台获取的结果</h1>
 9     {{ result }}
10      <input type="button" value="获取数据" onclick="getContent();" />
11      <div id="container"></div>
12      <script src="/static/jquery-1.12.4.js"></script>
13     <script>
14         function getContent(){
15            /*
16             var tag = document.createElement('script');
17             tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403';
18             document.head.appendChild(tag);
19             document.head.removeChild(tag);
20             */
21            $.ajax({
22                url: 'http://www.jxntv.cn/data/jmd-jxtv2.html',
23                type: 'POST',
24                dataType: 'jsonp',
25                jsonp: 'callback',
26                jsonpCallback: 'list'
27            })
28 
29         }
30         function list(arg){
31             console.log(arg);
32         }
33     </script>
34 </body>
35 </html>
req.html

9,xss过滤(防攻击)

 1 import os
 2 import json
 3 import uuid
 4 from django.shortcuts import render
 5 from django.shortcuts import HttpResponse
 6 from django.shortcuts import redirect
 7 from django.db import transaction
 8 from django.urls import reverse
 9 
10 from ..forms.article import ArticleForm
11 from ..auth.auth import check_login
12 from repository import models
13 from utils.pagination import Pagination
14 from utils.xss import XSSFilter
15 
16 
17 def add_article(request):
18     """
19     添加文章
20     :param request:
21     :return:
22     """
23     if request.method == 'GET':
24         form = ArticleForm(request=request)
25         return render(request, 'backend_add_article.html', {'form': form})
26     elif request.method == 'POST':
27         form = ArticleForm(request=request, data=request.POST)
28         if form.is_valid():
29 
30             with transaction.atomic():
31                 tags = form.cleaned_data.pop('tags')
32                 content = form.cleaned_data.pop('content')
33                 print(content)
34                 #调用防攻击类
35                 content = XSSFilter().process(content)
36                 form.cleaned_data['blog_id'] = request.session['user_info']['blog__nid']
37                 obj = models.Article.objects.create(**form.cleaned_data)
38                 models.ArticleDetail.objects.create(content=content, article=obj)
39                 tag_list = []
40                 for tag_id in tags:
41                     tag_id = int(tag_id)
42                     tag_list.append(models.Article2Tag(article_id=obj.nid, tag_id=tag_id))
43                 models.Article2Tag.objects.bulk_create(tag_list)
44 
45             return redirect('/backend/article-0-0.html')
46         else:
47             return render(request, 'backend_add_article.html', {'form': form})
48     else:
49         return redirect('/')
View Code
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from bs4 import BeautifulSoup
 4 
 5 
 6 class XSSFilter(object):
 7     __instance = None
 8 
 9     def __init__(self):
10         # XSS白名单
11         self.valid_tags = {
12             "font": ['color', 'size', 'face', 'style'],
13             'b': [],
14             'div': [],
15             "span": [],
16             "table": [
17                 'border', 'cellspacing', 'cellpadding'
18             ],
19             'th': [
20                 'colspan', 'rowspan'
21             ],
22             'td': [
23                 'colspan', 'rowspan'
24             ],
25             "a": ['href', 'target', 'name'],
26             "img": ['src', 'alt', 'title'],
27             'p': [
28                 'align'
29             ],
30             "pre": ['class'],
31             "hr": ['class'],
32             'strong': []
33         }
34 
35     def __new__(cls, *args, **kwargs):
36         """
37         单例模式
38         :param cls:
39         :param args:
40         :param kwargs:
41         :return:
42         """
43         if not cls.__instance:
44             obj = object.__new__(cls, *args, **kwargs)
45             cls.__instance = obj
46         return cls.__instance
47 
48     def process(self, content):
49         soup = BeautifulSoup(content, 'html.parser')
50         # 遍历所有HTML标签
51         for tag in soup.find_all(recursive=True):
52             # 判断标签名是否在白名单中
53             if tag.name not in self.valid_tags:
54                 tag.hidden = True
55                 if tag.name not in ['html', 'body']:
56                     tag.hidden = True
57                     tag.clear()
58                 continue
59             # 当前标签的所有属性白名单
60             attr_rules = self.valid_tags[tag.name]
61             keys = list(tag.attrs.keys())
62             for key in keys:
63                 if key not in attr_rules:
64                     del tag[key]
65 
66         return soup.decode()
67 
68 
69 if __name__ == '__main__':
70     html = """<p class="title">
71                         <b>The Dormouse's story</b>
72                     </p>
73                     <p class="story">
74                         <div name='root'>
75                             Once upon a time there were three little sisters; and their names were
76                             <a href="http://example.com/elsie" class="sister c1" style='color:red;background-color:green;' id="link1"><!-- Elsie --></a>
77                             <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
78                             <a href="http://example.com/tillie" class="sister" id="link3">Tilffffffffffffflie</a>;
79                             and they lived at the bottom of a well.
80                             <script>alert(123)</script>
81                         </div>
82                     </p>
83                     <p class="story">...</p>"""
84 
85     obj = XSSFilter()
86     v = obj.process(html)
87     print(v)
View Code

 

posted @ 2018-08-12 17:06  ༺༽秋水.无痕༼༻  阅读(140)  评论(0编辑  收藏  举报
……