第八章(6)
- modelform
- 原生ajax
- 上传文件,XMLHttpRequest,jquery,iframe
- XMLHttpRequest,jquery,iframe 应用场景
- 图片验证码 + session
- KindEdittor博客插件
- 前端组合搜索
- jsonp
- 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>
如果发送的是普通数--> 1,jquery 2,XMLHttpRequest 3,iframe 如果是文件 ----> 1,iframe 2,XMLHttpRequest(ajax和原生)
5,
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 ]
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)
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 )
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>
优化版
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)
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 )
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))
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>
8,jsonp
由于浏览器具有同源策略(阻止Ajax请求,无法阻止<script src='......'><script>)
巧妙:
- 创建scrIpt 标签
- src=远程地址
- 返回的数据必须是js格式
只能发GET请求
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 ]
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)
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
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>
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('/')
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)

浙公网安备 33010602011771号