python自动化开发-[第二十二天]-bbs多级评论、点赞、上传文件
今日概要:
1、related_name和related_query_name的区别
2、through_fields的用途
3、django的事务提交
4、点赞的动画效果
5、多级评论的原理
6、上传文件
7、request.post用法
8、如果保留原来的页面
一、related_name和related_query_name的区别
related_name,用于定义反向关联时候,使用的字段名称
related_query_name 用于反向查询related_query_name + _set进行查询
例子:
class A:
title = models.CharField()
obj = models.A.objects.get(id=1)
obj.b_set.all()
obj.xxxxxx_set.all() # related_query_name='xxxxxx'
obj.uuuu.all() # related_name='uuuu' obj.x
obj.u class B:
xx ..xx
fk1 = models.ForignKey(related_name='x')
fk2 = models.ManyToMany(related_name='u') models.B.objects.filter(fk__title='xx')
二、through_fields的用途
through_fields = (在关系表中与当前表建立FK关系的字段名称,在关系表中与目标表建立的FK关系字段名称)
例子:
likes = models.ManyToManyField(to='UserInfo',through="Like",through_fields=('new','user')) #当前表是new表
三、django的事务提交
保持两条sql的同时正确才进行插入动作
from django.db import transaction
with transaction.atomic():
models.Like.objects.create(nnew_id=new_id,uuser_id=uid)
models.News.objects.filter(id=new_id).update(like_count=F('like_count') + 1)
response.code = 999
返回值封装:
class BaseResponse(object):
def __init__(self):
self.status = False
self.data = None
self.msg = None def get_dict(self):
return self.__dict__ class LikeResponse(BaseResponse):
def __init__(self):
self.code = 0
super(LikeResponse,self).__init__() json.dumps(对象.__dict__)
json.dumps(对象.get_dict())
四、点赞的动画效果
*在ajax中操作回调函数中的 $(this)已经不是原来的$(this)
解决方法:通过一个变量来传递
应用内容:css中的position:fixed,absolute,relative setInterval:定时器
js代码:
$(function () {
bindLikeEvent();
});
function bindLikeEvent() {
$('.new-like').click(function () {
// 获取当前新闻ID
var newId = $(this).attr('new-id');
var $this = $(this);
$.ajax({
url: '/do_like.html',
type: "POST",
data: {'newId': newId},
dataType: 'JSON',
success:function (arg) {
if(arg.status){
var origin = $this.text();
var count = parseInt(origin);
if(arg.code == 666){
$this.text(count - 1 );
showLikeCount($this,'-1');
}else if(arg.code == 999){
$this.text(count + 1 );
showLikeCount($this,'+1');
}
}else{
alert(arg.msg);
}
}
})
})
}
function showLikeCount($this,text) {
var fontSize = 5;
var top = 0;
var right = 0;
var opacity = 1;
var tag = document.createElement('span');
tag.innerText = text;
tag.style.position = "absolute";
tag.style.fontSize = fontSize + "px";
tag.style.top = top + "px";
tag.style.right = right + "px";
tag.opacity = opacity;
$this.after(tag);
var obj = setInterval(function () {
fontSize += 5 ;
top -= 5;
right -= 5 ;
opacity -= 0.1 ;
tag.style.fontSize = fontSize + "px";
tag.style.top = top + "px";
tag.style.right = right + "px";
tag.style.opacity = opacity;
if (opacity <= 0 ){
clearInterval(obj);
tag.remove()
}
},100)
}
</script>
五、多级评论的原理
知识点:字典和列表,通过引用赋值,一个修改全部都改变
递归
#!/usr/bin/python
# -*- coding:utf-8 -*- def build_comment_data(li):
dic = {} #定义一个空字典dic
for item in li:
item['children'] = [] #列表字典中新增一个key叫children,value为空
dic[item['id']] = item #给空字典dic赋值 key是列表中字典中的id,value是列表字典 result = [] #定义一个空列表,存最后的结果 for item in li: #item是li列表中的每一行字典
pid = item['parent_id'] #pid是取每一行字典中parent_id的值
if pid: #如果每一行字典中parent_id有值
dic[pid]['children'].append(item) #则找到字典中pid的那一行,把item加到children里
else:
result.append(item) #否则把parent_id没有值的加到result列表中
# for i in result:
# print(i)
return result def build_comment_tree(com_list1):
tpl = """
<div class="item>
<div class="title">{0}:{1}</div>
<div class="body>{2}</div>
</div>
"""
#这里的{0}{1}{2}都是占位符 html=""
# print(com_list1)
# for i in com_list1:
# print(i)
for item in com_list1:
if not item['children']: #如果字典中没有children
html += tpl.format(item['user'],item['content'],"") #format给占位符传值,第三个值为空
else:
html += tpl.format(item['user'], item['content'], build_comment_tree(item['children']))
#如果有子children则把build_comment_tree函数自己再执行一遍,把孩子传进去(孩子也是一个完整的字典)
return html def comment_list():
li = [
{'id': 1, 'user': '银秋良', 'content': '灌我鸟事', 'parent_id': None},
{'id': 2, 'user': '银秋良', 'content': '管我鸟事', 'parent_id': None},
{'id': 3, 'user': '型谱', 'content': '你个文盲', 'parent_id': 1},
{'id': 4, 'user': '详解', 'content': '好羡慕你们这些没脸的人呀', 'parent_id': 2},
{'id': 5, 'user': '银秋良', 'content': '你是流氓', 'parent_id': 3},
{'id': 6, 'user': '银秋良', 'content': '你冷库无情', 'parent_id': 5},
{'id': 7, 'user': '银秋良', 'content': '你才冷酷无情', 'parent_id': 4},
{'id': 8, 'user': '银秋良', 'content': '你无理取闹', 'parent_id': 4},
]
com_list = build_comment_data(li) html = build_comment_tree(com_list)
print(html) if __name__ == '__main__':
comment_list()
知识回顾:
l = [1,2,4,5,6] #迭代器
for i in l: #迭代器对象
# 迭代器出现报错 l.__iter__() next()取到空的情况,迭代器对象不会 for j in l:
print(i)
引用类型应用:
li = [
{'user':'xxx','pwd':'xxx','id':1,"children":[],'parent_id':None},
{'user':'xxx','pwd':'xxx','id':2,"children":[],'parent_id':None},
{'user':'xxx','pwd':'xxx','id':3,"children":[],'parent_id':1},
{'user':'xxx','pwd':'xxx','id':4,"children":[],'parent_id':2},
{'user':'xxx','pwd':'xxx','id':5,"children":[],'parent_id':1},
{'user':'xxx','pwd':'xxx','id':6,"children":[],'parent_id':3},
]
#结果:
# result = [
# {'user':'xxx','pwd':'xxx','id':1,"children":[{'user':'xxx','pwd':'xxx','id':3,"children":[ {'user':'xxx','pwd':'xxx','id':6,"children":[],'parent_id':3},],'parent_id':1},{'user':'xxx','pwd':'xxx','id':5,"children":[],'parent_id':1},],'parent_id':None},
# {'user':'xxx','pwd':'xxx','id':2,"children":[{'user':'xxx','pwd':'xxx','id':4,"children":[],'parent_id':2},],'parent_id':None},
# ] dict = {}
for i in li:
dict[i['id']] = i a = []
for k,v in dict.items():
if v['parent_id']:
dict[v['parent_id']]["children"].append(v)
else:
a.append(v) print(a)
javascript实现多级评论:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.hide {
display: none;
}
.body{
margin-left: 30px;
} </style>
</head>
<body>
<h1>多级评论</h1>
<a id="a1" href="#" onclick="myClick()">点我</a>
{# {{ comment_list | safe }}#} <script src="/static/jquery-3.2.1.js"></script>
<script> function my_iter(arg) {
var h = "";
$.each(arg,function (k,v) {
if (v['children']){
h += '<div class="item"><div class="title">' + v['user'] + ':' + v['content'] + '</div> <div class="body">' + my_iter(v['children']) + '</div></div>'
}else{
h += '<div class="item"><div class="title">' + v['user'] + ':' + v['content'] + '</div><div class="body"></div></div>'
}
});
return h
} $(function () {
$('body').on('click',".title",function () {
if ($(this).next().hasClass('hide')){
$(this).next().removeClass('hide')
}else{
$(this).next().addClass('hide')
}
})
});
function myClick() {
$.ajax({
url:'/comment',
type:"POST",
data:"1",
dataType:"JSON",
success:function (arg) {
console.log(my_iter(arg));
$('#a1').after(my_iter(arg))
}
})
} </script>
</body>
</html>
六、上传文件
- 基于FormData
- 缺点,兼容性不好
- 优点,Ajax直接发送
- 伪Ajax,兼容性更好
- iframe,天生局部刷新
- form,天生整个页面刷新
七、request.post用法
- 如何通过python代码发送post数据?
URL: http://127.0.0.1:8003/asset.html 客户端:
import requests
# response = requests.get('http://127.0.0.1:8003/asset.html')
# print(response.text)
data_dict = {
'k1':'v1',
'k2':'v2'
}
# content-type: application/x-www-form-urlencoded
# response = requests.post('http://127.0.0.1:8003/asset.html',data=data_dict)
# print(response.text) # content-type: appcation/json
response = requests.post('http://127.0.0.1:8003/asset.html',json=data_dict)
print(response.text) 服务端Django:
from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_exempt
def asset(request):
if request.method == "GET":
return HttpResponse('收到:GET')
else:
print(request.POST)
print(request.body)
return HttpResponse('收到:POST')
八、如果保留原来的页面
request.GET
from django.http.request import QueryDict
要点:
POST,不要写action
例子:
def host_list(request):
print(request.GET,type(request.GET))
# request.GET._mutable = True obj = QueryDict(mutable=True)
obj['_zhaofengfeng'] = request.GET.urlencode() # page=10&id=1
url_param = obj.urlencode() hosts = ['c1.com','c2.com','c3.com']
return render(request,'host_list.html',{'hosts':hosts,'url_param':url_param}) def add_host(request):
if request.method == "GET":
return render(request,'add.html')
else:
url_params = request.GET.get('_zhaofengfeng')
host = request.POST.get('hostname')
url ="/host_list.html?"+url_params
return redirect(url)
python自动化开发-[第二十二天]-bbs多级评论、点赞、上传文件的更多相关文章
- python自动化开发-[第十二天]-前端html
今日概要: 前端基础之html 1.web服务器的本质: #!/usr/bin/python # -*- coding:utf-8 -*- import socket def handle_reque ...
- django高级之点赞、文章评论及上传文件
目录: 点赞 文章评论 上传文件 保留页面条件 一.点赞 1.所用技术: django model F查询 js应用:$(function () {}); 为文件加载完成执行ready() 方法.等同 ...
- Android开发(二十五)——Android上传文件至七牛
设置头像: Drawable drawable = new BitmapDrawable(dBitmap); //Drawable drawable = Drawable.createFromPath ...
- python自动化开发-[第二十四天]-高性能相关与初识scrapy
今日内容概要 1.高性能相关 2.scrapy初识 上节回顾: 1. Http协议 Http协议:GET / http1.1/r/n...../r/r/r/na=1 TCP协议:sendall(&qu ...
- python自动化开发-[第二十三天]-初识爬虫
今日概要: 1.爬汽车之家的新闻资讯 2.爬github和chouti 3.requests和beautifulsoup 4.轮询和长轮询 5.django request.POST和request. ...
- python自动化开发-[第二天]-基础数据类型与编码(续)
今日简介: - 编码 - 进制转换 - 初识对象 - 基本的数据类型 - 整数 - 布尔值 - 字符串 - 列表 - 元祖 - 字典 - 集合 - range/enumcate 一.编码 encode ...
- python自动化开发-[第二十五天]-scrapy进阶与flask使用
今日内容概要 1.cookie操作 2.pipeline 3.中间件 4.扩展 5.自定义命令 6.scrapy-redis 7.flask使用 - 路由系统 - 视图 - 模版 - message( ...
- python自动化开发-[第十二天]-前端Css
CSS基本语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. selector { property: value; property: value; ... property: v ...
- Linux下开发python django程序(设置admin后台管理上传文件和前台上传文件保存数据库)
1.项目创建相关工作参考前面 2.在models.py文件中定义数据库结构 import django.db import modelsclass RegisterUser(models.Model) ...
随机推荐
- Military Problem CodeForces 1006E (dfs序)
J - Military Problem CodeForces - 1006E 就是一道dfs序的问题 给定一个树, 然后有q次询问. 每次给出u,k, 求以u为根的子树经过深搜的第k个儿子,如果一个 ...
- 进程间通讯:有名管道FIFO
接收端: #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include < ...
- python 模块之-pickle
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关 ...
- [IOI2018]机械娃娃——线段树+构造
题目链接: IOI2018doll 题目大意:有一个起点和$m$个触发器,给出一个长度为$n$的序列$a$,要求从起点出发按$a$的顺序经过触发器并回到起点(一个触发器可能被经过多次也可能不被经过), ...
- C# int数组转string字符串
方式一:通过循环数组拼接的方式: int[] types = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; string result = string.Empty ...
- 【BZOJ5285】[HNOI2018]寻宝游戏(神仙题)
[BZOJ5285][HNOI2018]寻宝游戏(神仙题) 题面 BZOJ 洛谷 题解 既然是二进制按位的运算,显然按位考虑. 发现这样一个关系,如果是\(or\)的话,只要\(or\ 1\),那么无 ...
- 各种反演细节梳理&模板
炫酷反演魔术课件byVFK stO FDF Orz(证明全有%%%) 莫比乌斯反演 \(F(n)=\sum\limits_{d|n}f(d)\Rightarrow f(n)=\sum\limits_{ ...
- Codeforces Bubble Cup 11 J. Moonwalk challenge加强版
题意 有一棵 \(n\) 个节点的树,每条边上有一个字符,有 \(m\) 次询问. 每次会选定两个点 \(u, v\) , \(u\) 到 \(v\) 的路径上的字符形成了一个字符串 \(T\) ,再 ...
- 自学Python之路-django
自学Python之路-django 自学Python之路[第一回]:1.11.2 1.3
- rt-thread之串口设备的配置流程
@2019-01-30 [小记] > rt-thread 工程启动之后先是进入函数 rtthread_startup 做一些系统运行前的基础工作,主要有: * 板级硬件初始化 * 系统定时器初始 ...