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 ...
随机推荐
- JavaWeb学习笔记--HttpServletRequest、HttpServletResponse对象常用方法
HttpServletRequest HttpSession session = request.getSession(true); //获取会话对象 Cookie[] cookies = reque ...
- RAC之RMAN恢复
之前整理的RMAN 有关还原的文章: RMAN 系列(五) ---- RMAN 还原 与 恢复 http://blog.csdn.net/tianlesoftware/archive/2010/07/ ...
- Linux Shell Scripting Tutorial (LSST) v2.0
http://bash.cyberciti.biz/wiki/index.php?title=Main_Page
- 考查嵌入式C开发人员的最好的16道题
约定: 1) 下面的测试题中,认为所有必须的头文件都已经正确的包含了 2)数据类型 char 一个字节 1 byte int 两个字节 2 byte ( ...
- Source insight添加工具自动排版
当在网上找了一些别人的程序拿来学习,用Source insight来看时,会不会因为代码太乱看了义愤填膺呢? 有很多集成的开发环境可以自动排版,但source insight却不行!不过,有工具和配置 ...
- ./scripts/feeds update -a OpenWrt大招系列
./scripts/feeds update -a Updating feed 'packages' from 'https://github.com/openwrt/packages.git' .. ...
- 案例:用JS实现放大镜特效
案例:用JS实现放大镜特效 案例:用JS实现放大镜特效
- js网页返回页面顶部的小方法
咳咳,在网页出现滚动条的时候,许多网站会在右下角出现一个图标,点击可以回到页面顶部 本文就记录下js实现代码: 1.在html页面body添加dom元素 <img src="toTop ...
- 异步套接字基础:select函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
参考:[原创]技术系列之 网络模型(三)多路复用模型 select函数 select函数: 系统提供select函数来实现多路复用输入/输出模型.原型: #include <sys/time.h ...
- SPRING+JNDI+C3P0 in tomcat6
Tomcat 中Jndi是使用Tomcat自带的连接池,由于客户要求,抛弃Tomcat自带的连接池.使用c3p0 .经过几个小时调试,解决方案如下: 环境:Tomcat 6 下面来看Jndi 与 c3 ...