今日概要:

  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多级评论、点赞、上传文件的更多相关文章

  1. python自动化开发-[第十二天]-前端html

    今日概要: 前端基础之html 1.web服务器的本质: #!/usr/bin/python # -*- coding:utf-8 -*- import socket def handle_reque ...

  2. django高级之点赞、文章评论及上传文件

    目录: 点赞 文章评论 上传文件 保留页面条件 一.点赞 1.所用技术: django model F查询 js应用:$(function () {}); 为文件加载完成执行ready() 方法.等同 ...

  3. Android开发(二十五)——Android上传文件至七牛

    设置头像: Drawable drawable = new BitmapDrawable(dBitmap); //Drawable drawable = Drawable.createFromPath ...

  4. python自动化开发-[第二十四天]-高性能相关与初识scrapy

    今日内容概要 1.高性能相关 2.scrapy初识 上节回顾: 1. Http协议 Http协议:GET / http1.1/r/n...../r/r/r/na=1 TCP协议:sendall(&qu ...

  5. python自动化开发-[第二十三天]-初识爬虫

    今日概要: 1.爬汽车之家的新闻资讯 2.爬github和chouti 3.requests和beautifulsoup 4.轮询和长轮询 5.django request.POST和request. ...

  6. python自动化开发-[第二天]-基础数据类型与编码(续)

    今日简介: - 编码 - 进制转换 - 初识对象 - 基本的数据类型 - 整数 - 布尔值 - 字符串 - 列表 - 元祖 - 字典 - 集合 - range/enumcate 一.编码 encode ...

  7. python自动化开发-[第二十五天]-scrapy进阶与flask使用

    今日内容概要 1.cookie操作 2.pipeline 3.中间件 4.扩展 5.自定义命令 6.scrapy-redis 7.flask使用 - 路由系统 - 视图 - 模版 - message( ...

  8. python自动化开发-[第十二天]-前端Css

    CSS基本语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. selector { property: value; property: value; ... property: v ...

  9. Linux下开发python django程序(设置admin后台管理上传文件和前台上传文件保存数据库)

    1.项目创建相关工作参考前面 2.在models.py文件中定义数据库结构 import django.db import modelsclass RegisterUser(models.Model) ...

随机推荐

  1. Linux命令替换字符串

    :%s/str1/str2/ 用str2替换str1

  2. Express static 托管静态文件 理解

    今天偶尔看了一下服务端渲染,遇到了express.static, 在以前学习webpack配置服务端渲染时,也使用express.static 中间件,两者配置不太一样,由于当时也没有认真学,所以 一 ...

  3. JAVA-Web 百度编辑器,修改默认大小

    百度UEditor富文本编辑器-设置默认字体.字号.行间距及添加字体种类 如果这个还不能改变大小了,找一下在文件夹UEditor--css--中default.css文件,搜索出红色部分: grid_ ...

  4. .net core 2.0 Autofac

    参考自 https://github.com/VictorTzeng/Zxw.Framework.NetCore 安装Autofac,在`project.csproj`加入 <PackageRe ...

  5. Python中pandas模块解析

    Pandas基于两种数据类型: series 与 dataframe . 1.Series 一个series是一个一维的数据类型,其中每一个元素都有一个标签.类似于Numpy中元素带标签的数组.其中, ...

  6. P1064 金明的预算方案

    思路:就是一个背包问题  因为数据范围小,所以不把 1个带附着物的东西 拆成 带1个带2个或不带 #include<bits/stdc++.h> using namespace std; ...

  7. robotframework编写用例

    ** Test Cases *** Test With Settings [Documentation] Another dummy test # 用于指定测试用例文档 [Tags] dummy ow ...

  8. swagger2 如何匹配多个controller

    方法一:使用多个controller的共同拥有的父类,即精确到两个controller的上一级 @Bean public Docket createRestApi() { return new Doc ...

  9. 【cf789D】Weird journey(欧拉路、计数)

    cf788B/789D. Weird journey 题意 n个点m条边无重边有自环无向图,问有多少种路径可以经过m-2条边两次,其它两条边1次.边集不同的路径就是不同的. 题解 将所有非自环的边变成 ...

  10. 图论杂项细节梳理&模板(虚树,圆方树,仙人掌,欧拉路径,还有。。。)

    orzYCB 虚树 %自为风月马前卒巨佬% 用于优化一类树形DP问题. 当状态转移只和树中的某些关键点有关的时候,我们把这些点和它们两两之间的LCA弄出来,以点的祖孙关系连成一棵新的树,这就是虚树. ...