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) ...
随机推荐
- git使用常见问题
1.git branch使用,创建新的分之后做修改后,其他分支也被同步修改 问题: 原项目在 master 分支,执行下面的操作: git branch test git checkout tes ...
- 前端部分-CSS基础介绍
CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素.也就是定义相应的标签语言来定制显示样式达到一定的显示效果. 每个CSS样式由两个组成部分:选择器和 ...
- Python3入门基础--str常用方法
Python基础之String常用方法 str():将其他类型的变量转换为str类型,例如: name = 'Jack' age = 22 course = ['web','Java','mysql' ...
- pytorch CNN 手写数字识别
一个被放弃的入门级的例子终于被我实现了,虽然还不太完美,但还是想记录下 1.预处理 相比较从库里下载数据集(关键是经常失败,格式也看不懂),更喜欢直接拿图片,从网上找了半天,最后从CSDN上下载了一个 ...
- 百度APP爬虫
1.抓包 访问一个频道,Charles抓包,找到真实连接,一般返回json数据和网页中数据对应为真实连接 请求方式为post,所以要添加请求头和表单数据,由于在charles环境下,所以要添加char ...
- MT【260】单调函数
设$f(x)$是定义在$(0,+\infty)$上的单调函数,且对定义域内的任意实数$x$,都有$f(f(x)-\log_2 x)=3$, 求$f(x)-f^{'}(x)=2$的解所在的区间.____ ...
- awk文本分析工具
Usage:awk [option] 'program' file ... awk [option] -f progfile file ... [optin]: -F fs 指定输入分隔符,fs可是字 ...
- Android平台如何获得屏幕尺寸?
本文选自StackOverflow(简称:SOF)精选问答汇总系列文章之一,本系列文章将为读者分享国外最优质的精彩问与答,供读者学习和了解国外最新技术,本文为大家讲解在Android平台上如何获得屏幕 ...
- Luogu P5283 / LOJ3048 【[十二省联考2019]异或粽子】
联考Day1T1...一个考场上蠢了只想到\(O(n^2)\)复杂度的数据结构题 题目大意: 求前\(k\)大区间异或和的和 题目思路: 真的就是个sb数据结构题,可持久化01Trie能过(开O2). ...
- layui laydate is not defined
记得引入的js文件要放到layui.js前面才会生效