- 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{ 100px;height: 50px;opacity: 0; position: absolute; top:0; right:0; left:0; z-index:100; } </style> </head> <body> <div style="position: relative; 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=" 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)