python运维开发(二十二)---JSONP、瀑布流、组合搜索、多级评论、tornado框架简介
内容目录:
- JSONP应用
- 瀑布流布局
- 组合搜索
- 多级评论
- tornado框架简介
JSONP应用
由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。
特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了。
浏览器同源策略并不是对所有的请求均制约:
- 制约: XmlHttpRequest
- 不制约(不生效)的标签: img、iframe、script等具有src属性的标签
JSONP(JSONP - JSON with Padding是JSON的一种“使用模式”),利用script标签的src属性(浏览器允许script标签跨域)
几种方式的对比查看,本机访问另一个域名方式采用另一个django项目方式
访问过程中需要绑定hosts 127.0.0.1 jabe.com
django项目jsonp1
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^get_data/', views.get_data),
url code
from django.shortcuts import render,HttpResponse # Create your views here. def index(request): return render(request,'index.html') def get_data(request): return HttpResponse('ok')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>Index</h1> <input type="button" onclick="Ajax();" value="普通AJax"/> <input type="button" onclick="Ajax2();" value="跨域普通AJax"/> <input type="button" onclick="Ajax3();" value="跨域牛逼AJax"/> <input type="button" onclick="Ajax4();" value="江西TV"/> <script src="/static/jquery-2.1.4.min.js"></script> <script> function Ajax(){ $.ajax({ url: '/get_data/', type: 'POST', data: {'k1': 'v1'}, success: function (arg) { alert(arg); } }) } function Ajax2(){ $.ajax({ url: 'http://jabe.com:8001/api/', type: 'GET', data: {'k1': 'v1'}, success: function (arg) { alert(arg); } }) } function Ajax3(){ // script // alert(api) var tag = document.createElement('script'); tag.src = 'http://jabe.com:8001/api/'; document.head.appendChild(tag); document.head.removeChild(tag); } function fafafa(arg){ console.log(arg); } function Ajax4(){ // script // alert(api) var tag = document.createElement('script'); tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'; document.head.appendChild(tag); document.head.removeChild(tag); } function list(arg){ console.log(arg); } </script> </body> </html>
index html code
第二个项目jsonp2
from django.conf.urls import url from django.contrib import admin from app001 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^api/', views.api), ]
url code
def api(request): li = ['jabe', 'ljb', 'tony'] temp = "fafafa(%s)" %(json.dumps(li)) return HttpResponse(temp)
同时可以直接设置ajax发送请求类型设置为JSONP,即dataType:JSONP,
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <p> <input type="button" onclick="Jsonp1();" value='提交'/> </p> <p> <input type="button" onclick="Jsonp2();" value='提交'/> </p> <script type="text/javascript" src="jquery-1.12.4.js"></script> <script> function Jsonp1(){ var tag = document.createElement('script'); tag.src = "http://c2.com:8000/test/"; document.head.appendChild(tag); document.head.removeChild(tag); } function Jsonp2(){ $.ajax({ url: "http://c2.com:8000/test/", type: 'GET', dataType: 'JSONP', success: function(data, statusText, xmlHttpRequest){ console.log(data); } }) } </script> </body> </html>
demo
jsonp的callback和list
dataType: jsonp jsonp: 'callback', jsonpCallback: 'list' function list(arg){ console.log(arg); } - jsonp: callback # request.GET.get("callback") - jsonpCallback: 'list' # list(...)
jsonp不能发送POST请求
==> 最终全部都会转换成GET请求
扩展
CORS-跨站资源共享,浏览器版本要求
瀑布流布局
在实际的环境中我们的网页可能会出现并排的布局,但是图片和内容大小不一致,我们希望下面并排挨着上面紧凑布局方式,因此就用到了瀑布流布局。
实例展示
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^student/', views.student), ]
url code
from django.shortcuts import render # Create your views here. def student(request): img_list = [ { { {'src': '3.jpg', 'title': 'asdfasdfasdf','content': 'asdf'}, {'src': '4.jpg', 'title': 'asdfasdfasdf','content': 'asdf'}, { {'src': '21.jpg', 'title': 'asdfasdfasdf','content': 'asdf'}, ] return render(request, 'student.html', {"img_list":img_list})
{% load xx %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .container{ width: 980px; margin: 0 auto; } .container .column{ float: left; width: 245px; } .container .item img{ width: 245px; } </style> </head> <body> <div class="container"> <div class="column"> {% for i in img_list %} {% if forloop.counter|detail1:"4,1" %} <div class="item"> {{ forloop.counter }} <img src="/static/{{ i.src }}"> </div> {% endif %} {% endfor %} </div> <div class="column"> {% for i in img_list %} {% if forloop.counter|detail1:"4,2" %} <div class="item"> {{ forloop.counter }} <img src="/static/{{ i.src }}"> </div> {% endif %} {% endfor %} </div> <div class="column"> {% for i in img_list %} {% if forloop.counter|detail1:"4,3" %} <div class="item"> {{ forloop.counter }} <img src="/static/{{ i.src }}"> </div> {% endif %} {% endfor %} </div> <div class="column"> {% for i in img_list %} {% if forloop.counter|detail1:"4,0" %} <div class="item"> {{ forloop.counter }} <img src="/static/{{ i.src }}"> </div> {% endif %} {% endfor %} </div> </div> </body> </html>
student html code
# Author:Alex Li from django import template from django.utils.safestring import mark_safe from django.template.base import resolve_variable, Node, TemplateSyntaxError register = template.Library() @register.filter def detail1(value,arg): """ 查看余数是否等于remainder arg="1,2" :param counter: :param allcount: :param remainder: :return: """ allcount, remainder = arg.split(',') allcount = int(allcount) remainder = int(remainder) if value%allcount == remainder: return True return False
templatetags xx.py
组合搜索
在很多的电商网站类似京东和淘宝都有多级组合的筛选条件来找到自己想要的商品,我们来做一下这个组合搜索的功能
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^student/', views.student), url(r'^video-(?P<direction_id>\d+)-(?P<classfication_id>\d+)-(?P<level_id>\d+).html', views.video), ]
Url Code
from django.shortcuts import render from app01 import models # Create your views here. def video(request,**kwargs): print(kwargs) print(request.path_info) current_url = request.path_info direction_id = kwargs.get(') classfication_id = kwargs.get(') q = {} # 方向是0 ': cList = models.Classification.objects.values('id', 'name') # 分类是0 ': # video-0-0 pass else: # video-0-1 # 选中了某个分类 q['classification__id'] = classfication_id else: obj = models.Direction.objects.get(id=direction_id) temp = obj.classification.all().values('id','name') id_list = list(map(lambda x:x['id'],temp)) cList = obj.classification.all().values('id','name') ': # video-1-0 # 根据风向ID,找到所属的分类ID print(id_list) q['classification__id__in'] = id_list else: # video-1-1 if int(classfication_id) in id_list: q['classification__id'] = classfication_id else: q['classification__id__in'] = id_list url_list = current_url.split('-') url_list[2] = " current_url = '-'.join(url_list) level_id = kwargs.get('level_id',None) ': q['level'] = level_id result = models.Video.objects.filter(**q) dList = models.Direction.objects.values('id', 'name') lList = models.Video.level_choice # level_choice = ( # (1, u'初级'), # (2, u'中级'), # (3, u'高级'), # ) return render(request, 'video.html', {"dList":dList, 'cList': cList, 'lList': lList, 'current_url': current_url})
from django.db import models # 技术方向, class Direction(models.Model): name = models.CharField(verbose_name='名称', max_length=32) classification = models.ManyToManyField('Classification') class Meta: db_table = 'Direction' verbose_name_plural = u'方向(视频方向)' def __str__(self): return self.name # 技术分类、语言 class Classification(models.Model): name = models.CharField(verbose_name='名称', max_length=32) class Meta: db_table = 'Classification' verbose_name_plural = u'分类(视频分类)' def __str__(self): return self.name # 技术视频, class Video(models.Model): level_choice = ( (1, u'初级'), (2, u'中级'), (3, u'高级'), ) level = models.IntegerField(verbose_name='级别', choices=level_choice, default=1) classification = models.ForeignKey('Classification', null=True, blank=True) title = models.CharField(verbose_name='标题', max_length=32) summary = models.CharField(verbose_name='简介', max_length=32) img = models.ImageField(verbose_name='图片', upload_to='./static/images/Video/') href = models.CharField(verbose_name='视频地址', max_length=256) create_date = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'Video' verbose_name_plural = u'视频' def __str__(self): return self.title
Models Code
{% load xx %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .condition a{ display: inline-block; padding: 5px; } .condition a.active{ background-color: coral; color: white; } </style> </head> <body> <div class="condition"> <div> {% all_menu current_url %} : {% for i in dList %} {% ac1 current_url i.id i.name %} {% endfor %} </div> <div> {% for i in cList %} {% ac2 current_url i.id i.name %} {% endfor %} </div> <div> {% for i in lList %} {% ac3 current_url i.0 i.1 %} {% endfor %} </div> </div> </body> </html>
Video html Code
多级评论
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^comment/', views.comment), ]
url code
from django.shortcuts import render import collections # Create your views here. def tree_search(d_dic, comment_obj): # 在comment_dic中一个一个的寻找其回复的评论 # 检查当前评论的 reply_id 和 comment_dic中已有评论的nid是否相同, # 如果相同,表示就是回复的此信息 # 如果不同,则需要去 comment_dic 的所有子元素中寻找,一直找,如果一系列中未找,则继续向下找 for k, v_dic in d_dic.items(): # 找回复的评论,将自己添加到其对应的字典中,例如: {评论一: {回复一:{},回复二:{}}} if k[0] == comment_obj[2]: d_dic[k][comment_obj] = collections.OrderedDict() return else: # 在当前第一个跟元素中递归的去寻找父亲 tree_search(d_dic[k], comment_obj) def build_tree(comment_list): comment_dic = collections.OrderedDict() for comment_obj in comment_list: if comment_obj[2] is None: # 如果是根评论,添加到comment_dic[评论对象] = {} comment_dic[comment_obj] = collections.OrderedDict() else: # 如果是回复的评论,则需要在 comment_dic 中找到其回复的评论 tree_search(comment_dic, comment_obj) return comment_dic comment_list = [ (1, ', None), (2, ', None), (3, ', None), (9, ', 5), (4, ', 2), (5, ', 1), (6, ', 4), (7, ', 2), (8, ', 4), ] def comment(request): comment_dict = build_tree(comment_list) return render(request, 'comment.html', {'comment_dict': comment_dict})
Views Code
from django.db import models # Create your models here. class SendMsg(models.Model): nid = models.AutoField(primary_key=True) code = models.CharField(max_length=6) email = models.CharField(max_length=32, db_index=True) times = models.IntegerField(default=0) ctime = models.DateTimeField() class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32, unique=True) password = models.CharField(max_length=32) email = models.CharField(max_length=32, unique=True) ctime = models.DateTimeField() class NewsType(models.Model): nid = models.AutoField(primary_key=True) caption = models.CharField(max_length=32) class News(models.Model): nid = models.AutoField(primary_key=True) user_info = models.ForeignKey('UserInfo') news_type = models.ForeignKey('NewsType') title = models.CharField(max_length=32, db_index=True) url = models.CharField(max_length=128) content = models.CharField(max_length=50) favor_count = models.IntegerField(default=0) comment_count = models.IntegerField(default=0) ctime = models.DateTimeField() class Favor(models.Model): nid = models.AutoField(primary_key=True) user_info = models.ForeignKey('UserInfo') news = models.ForeignKey('News') ctime = models.DateTimeField() class Meta: unique_together = (("user_info", "news"),) class Comment(models.Model): nid = models.AutoField(primary_key=True) user_info = models.ForeignKey('UserInfo') news = models.ForeignKey('News') up = models.IntegerField(default=0) down = models.IntegerField(default=0) ctime = models.DateTimeField() device = models.CharField(max_length=16) content = models.CharField(max_length=150) reply_id = models.ForeignKey('Comment', related_name='b', null=True, blank=True)
Models Code
#!/usr/bin/env python # -*- coding:utf-8 -*- from django import template from django.utils.safestring import mark_safe register = template.Library() TEMP1 = """ <div class='content' style='margin-left:%s;'> <span>%s</span> """ def generate_comment_html(sub_comment_dic, margin_left_val): html = '<div class="comment">' for k, v_dic in sub_comment_dic.items(): html += TEMP1 % (margin_left_val, k[1]) if v_dic: html += generate_comment_html(v_dic, margin_left_val) html += "</div>" html += "</div>" return html @register.simple_tag def tree(comment_dic): html = '<div class="comment">' for k, v in comment_dic.items(): html += TEMP1 % (0, k[1]) html += generate_comment_html(v, 30) html += "</div>" html += '</div>' return mark_safe(html)
templatetags xx.py
{% load xx %} {% tree comment_dict %}
comment html code
Tornado框架简介
Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本。这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。(关于如何扩容 服务器,以处理数以千计的客户端的连接的问题,请参阅 C10K problem。)
安装:
pip3 install tornado
简单应用
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") application = tornado.web.Application([ (r"/index", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
执行过程:
- 第一步:执行脚本,监听 8888 端口
- 第二步:浏览器客户端访问 /index --> http://127.0.0.1:8888/index
- 第三步:服务器接受请求,并交由对应的类处理该请求
- 第四步:类接受到请求之后,根据请求方式(post / get / delete ...)的不同调用并执行相应的方法
- 第五步:方法返回值的字符串内容发送浏览器
参考url:http://www.cnblogs.com/wupeiqi/articles/5702910.html
python运维开发(二十二)---JSONP、瀑布流、组合搜索、多级评论、tornado框架简介的更多相关文章
- Python运维开发基础09-函数基础【转】
上节作业回顾 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 实现简单的shell命令sed的替换功能 import ...
- Python运维开发基础10-函数基础【转】
一,函数的非固定参数 1.1 默认参数 在定义形参的时候,提前给形参赋一个固定的值. #代码演示: def test(x,y=2): #形参里有一个默认参数 print (x) print (y) t ...
- Python运维开发基础08-文件基础【转】
一,文件的其他打开模式 "+"表示可以同时读写某个文件: r+,可读写文件(可读:可写:可追加) w+,写读(不常用) a+,同a(不常用 "U"表示在读取时, ...
- Python运维开发基础07-文件基础【转】
一,文件的基础操作 对文件操作的流程 [x] :打开文件,得到文件句柄并赋值给一个变量 [x] :通过句柄对文件进行操作 [x] :关闭文件 创建初始操作模板文件 [root@localhost sc ...
- Python运维开发基础06-语法基础【转】
上节作业回顾 (讲解+温习120分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 添加商家入口和用户入口并实现物 ...
- Python运维开发基础05-语法基础【转】
上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python # -*- coding:utf-8 -*- # author:Mr.chen import os,time Tag = ...
- Python运维开发基础04-语法基础【转】
上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 仅用列表+循环实现“简单的购物车程 ...
- Python运维开发基础03-语法基础 【转】
上节作业回顾(讲解+温习60分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen #只用变量和字符串+循环实现“用户登陆 ...
- Python运维开发基础02-语法基础【转】
上节作业回顾(讲解+温习60分钟) #!/bin/bash #user login User="yunjisuan" Passwd="666666" User2 ...
随机推荐
- WordPress插件制作教程(四): 将数据保存到数据库
上一篇讲解了添加菜单的方法,这一篇为大家讲解如何将数据保存到数据库中,并且显示在页面上,不会因提交表单时刷新页面输入框中内容消失.要实现这一功能我们需要借助WordPress函数来实现,下面就来讲解具 ...
- PHP & JAVA 实现 PBKDF2 加密算法
PHP代码: /** * PBKDF2 加密函数 * 参考标准 * @link https://www.ietf.org/rfc/rfc2898.txt * * php官方函数将在php5.5发布 * ...
- Linux_Shell type
Recommendation is to use the bash shell, because he is strong enough, and absorbed the useful proper ...
- IC封装形式COF介绍
其实这个真不太懂,没有太多接触也没有比较好的资料,只能简单的了解一下了. 什么是卷带式覆晶薄膜封装 COF(Chip on film) COF是一种 IC 封装技术,是运用软性基板电路(flexibl ...
- AOI
AOI(Automatic Optic Inspection)的全称是自动光学检测,是基于光学原理来对焊接生产中遇到的常见缺陷进行检测的设备.AOI是新兴起的一种新型测试技术,但发展迅速,很多厂家都推 ...
- Oracle ORA-03137: TTC protocol internal error : [12333] 故障分析
程序通过JDBC 连接数据库异常,报 ORA-03137[12333]的错误. 当前程序的JDBC 驱动版本:ojdbc16-11.2.0.1.0.jar 数据库版本: 11.2.0.3 一. Log ...
- bzoj1752 [Usaco2005 qua]Til the Cows Come Home
Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...
- 【HDU2795】Billboard(线段树)
大意:给一个h*w的格子,然后给出多个1*w的板子往格子里面填,如果有空间尽量往上一行填满,输出行数,无法填补,则输出-1: 可以使用线段树转化问题,将每一排的格子数目放到每一个叶子节点上,然后每有一 ...
- dig命令(转载)
dig命令使用大全(linux上域名查询) 可以这样说,翻译本篇文档的过程就是我重新学习DNS的过程,dig命令可以帮助我们学习DNS的原理,配置,以及其查询过程.以前使用dig仅仅是查询一下A记录或 ...
- python json基础学习01
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' import json #全称(javascript object ...