详情页,有几块是可以重复用的,一块是左上角的网站标志,一个是右上角和右侧分别的注册和排行,还有就是下面的简价。
新闻详情页有这个,新闻列表页也有。
所以如何抽取模板呢?
张大山那里如果实现呢?那里应该是不同的
1下面的排行如何实现
2登录注册如何实现,显示是哪个用户登录了
取出的是新闻列表,但是是按照阅读量排序的
用order_by(clicks)
ranknews = News.objects.all().order_by(clicks).limit(6)
{“ranknews”:ranknews}
def index():
取出用户,
要用户id,但是现在的用户信息可以随时取出来,因为在全局变量里,
user
取出分类
categoryf = Category.query.all()
categoryflist = []
for cate in categoryf # cate 是一个对象,而categoryf是一个对象列表。
categoryflist.append(cate.to_dict) # 把对象转换成字典,再把字典加到列表中
取出新闻
newsrank = News.query.order_by(News.clicks()).limit(constants.CLICK_RANK_MAX_NEWS)
newsranklist = []
for newsrank1 in newsrank # cate 是一个对象,而categoryf是一个对象列表。
newsranklist.append(newsrank.to_dict) # 把对象转换成字典,再把字典加到列表中
a = {
'categoryyflist':categoryflist,
'newsranklist':newsranklist,
}
return temples('index.html', a = a)
新闻列表实现
是通过获取到分类,然后呢,通过点击拿到分类,再把分类的新闻取出来,用group?,还是有分类.news?方法。如何实现分页呢?
详情页
收藏 如何实现的呢?
收藏一定是一个ajax的行为,只会有javascript行为发生,收藏在后端是什么行为呢?发送一个信息,然后后端做个什么?做完后给前端一个信息,收藏成功了,前端得到信号,执行javascript操作。
用户多了一篇收藏的文章 ,文章 多了一个收藏的用户,多对多的关系 。
collection =
如何定义模型类作者,模型类书籍。换成新经资讯这个项目。如何定义用户和发表的新闻之间,是一对多的关系 。一个新闻分类也可以有多条新闻。
换成天天生鲜项目呢?有哪些关系是一对多呢?用户和商品?商品和商品分类之间
定义用户如何定义?
用flask:
class Author(db.Model):
tablename = ‘author’
id = db.collurm(db.Integer, primary_key = True )
name = db.collurm(db.String(32), unique = True, )
au_book = db.relationship(Book, backref = ‘author’, lazy = ‘dynamic’)
class Book(db.Model):
tablename = ‘book’
id =
name =
log =
image =
author_id = db.collurm(db.Integer, db.Foreignkey(‘author.id’))
确定用户的属性怎么分析?去用户中心。
user:
1签名
2昵称
3性别
4头像
我的关注:只是user之间的关系,不是属性
5密码
我的收藏:用户跟文章之间的多对多关系。
新闻发布:新闻和用户之间的一对多关系
新闻列表:同上
天天生鲜用户模型分析:
收货地址:一个用户可以有多个收货地址。用户和收货地址间一对多关系。
当前地址:在地址属性里增加一个属性,是否选中,用0和1区别。
编辑地址:
个人信息:
1用户名
2联系电话
3地址
最近游览:商品属性里有一个最近被用户看过的属性
全部订单:用户和订单之间的一对多关系。
订单模型:
1创建时间
2订单号
3用户id
4订单与订单商品一对多的关系。
5支付状态,用0和1
地址模型:
收件人
地址
邮编
手机
用户id
是否选中为当前地址
评论模型:
1id
2和用户之间的关系,多对一
和新闻之间的关系,多对一,但是这个项目中没有要求显示出一个用户有哪些评论,只要求一篇文章有哪些评论
3子评论,也就是一对多的关系 ,只是这个一对多是对着自己。所以有一个父亲的属性
技巧:先设计大致的数据库关系表,然后再随着业务逻辑的进行增加相应的字段。
详情页后端:
@app.route(‘/news/<news_id>’)
def detail(news_id):
取到数据
检验有效性
根据参数取到新闻
new = News.query.get(news_id)
new1 = new.dict()
把取到数据和html返回给浏览器
点击排行
- {% for rank in randnews %}
- {{ loop }}{{ rank.title }}
- {% endfor %}
{% extends ‘news/base.html’ %}
{% block titleBlock %}
文章详情页
{% endblock %}
{% block scriptBlock %}
{% endblock %}
{% block contentBlock %}
前端显示的时候,用取到的对象.属性,依次显示文章的来源,内容,创建时间,阅读次数,摘要。
data.new1(取到的新闻字典).title,.creattime…
{% endblock %}
{% block authorBlock %}
根据这篇文章,得到作者的id,得到作者的id,拿到作者这个对象,然后就可以显示作者的信息,作者的文章数
author.news_list.count
author.nick_name
粉丝数:
author.followers.count
!笔记:这里我犯了个错误,可以直接在html中,news.author.followers_count。因为在类中已经帮助我处理了followers_count:self.followers.count
点关注的话,前端javascript
后端数据库是什么处理呢?
文章的作者多一个粉丝,我关注了他,关系型数据库,
author.followers.append(user)
{% endblock %}
发表评论前端:
作者,评论,文章
后端的处理,拿到数据
检验数据
数据库操作:
增加一条评论数据
commend = Commend()
commend.user_id = user_id
commend.news_id = news_id
是怎么拿到用户和新闻Id的呢?
commend.content = content
评论数:
new1.commends
展示评论列表:
commends = commens.query.filter(commend.news_id = news.id)
“”"
一个是内容,一个是作者信息,还有一个是下面的收藏评论
“”"
{% extends ‘news/base.html’ %}
{% block titleBlock %}
文章详情页
{% endblock %}
{% block scriptBlock %}
{% endblock %}
{% block contentBlock %}
前端显示的时候,用取到的对象.属性,依次显示文章的来源,内容,创建时间,阅读次数,摘要。
data.new1(取到的新闻字典).title,.creattime…
{% endblock %}
{% block authorBlock %}
根据这篇文章,得到作者的id,得到作者的id,拿到作者这个对象,然后就可以显示作者的信息,作者的文章数
author.news_list.count
author.nick_name
粉丝数:
author.followers.count
!笔记:这里我犯了个错误,可以直接在html中,news.author.followers_count。因为在类中已经帮助我处理了followers_count:self.followers.count
点关注的话,前端javascript
后端数据库是什么处理呢?
文章的作者多一个粉丝,我关注了他,关系型数据库,
author.followers.append(user)
{% endblock %}
发表评论前端:
作者,评论,文章
后端的处理,拿到数据
检验数据
数据库操作:
增加一条评论数据
commend = Commend()
commend.user_id = user_id
commend.news_id = news_id
是怎么拿到用户和新闻Id的呢?
commend.content = content
评论数:
new1.commends
展示评论列表:
commends = commens.query.filter(commend.news_id = news.id)
“”"
一个是内容,一个是作者信息,还有一个是下面的收藏评论
“”"
###收藏的后端实现
拿到ajax传过来的数据,现在是收藏和取消收藏都是一个函数处理,那么点击的时候,有什么不一样吗?它是两个ajax函数来实现的,
if action = collect:
如果写入到数据库成功
那么返回给ajax一个errno = 0;
ajax根据这个errno,
隐藏自己,显示"取消收藏按"
接收数据
a = request.jsonfy(params) !笔记:这里在哪里找参数呢?如果是表单提交,在哪里找数据?这里在前端就转成字符了。
new_id = request.json.get('news_id')
action = request.json.get(‘action’)
new_id = a.news_id
action = a.action
数据有效性?
if not all[new_id, action]
输出错误,?问题:如何输出?
数据库
加入user到new_id这文章的收藏属性中
?问题:这里基础知识不足,
返回成功与否的信号,if 不需要返回html和context:
@news_blu.route(‘/news_collect’, methods=[“POST”])
@user_login_data
def collect_news():
“”"
收藏新闻
1. 接受参数
2. 判断参数
3. 查询新闻,并判断新闻是否存在
:return:
“”"
user = g.user
if not user:
return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
# 1. 接受参数
news_id = request.json.get("news_id")
action = request.json.get("action")
# 2. 判断参数
if not all([news_id, action]):
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
if action not in ["collect", "cancel_collect"]:
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
try:
news_id = int(news_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
# 3. 查询新闻,并判断新闻是否存在
try:
news = News.query.get(news_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="数据查询错误")
if not news:
return jsonify(errno=RET.NODATA, errmsg="未查询到新闻数据")
# 4. 收藏以及取消收藏
if action == "cancel_collect":
# 取消收藏
if news in user.collection_news:
user.collection_news.remove(news)
else:
# 收藏
if news not in user.collection_news:
# 添加到用户的新闻收藏列表
user.collection_news.append(news)
return jsonify(errno=RET.OK, errmsg="操作成功")
###收藏函数:
def detial():
user = g.user
new_id = request.json.get(‘news_id’)
action = request.json.get(‘action’)
if not all[new_id, action]:
“参数错误”
news = News.query.get(News.id = new_id)
if action = “cancel_collect”
try:
user.collection_news.remove(news)
if action = "collect":
user.collection_news.append(news)
?问题:如何返回给前端成功的信号?
return jsonify(errno=RET.OK, errmsg="操作成功")
return jsonify(errno=RET.OK, errmsg="操作成功")
###评论功能的前后端:
def commend():
user = g.user
new_id = request.json.get(‘news_id’)
comment = request.json.get(‘comment’)
if not comment:
return josnfy"请输入评论"
news = News.query.get(News.id = new_id)
if action = “cancel_collect”
try:
user.collection_news.remove(news)
if action = “collect”:
user.collection_news.append(news)
?问题:如何返回给前端成功的信号?
return jsonify(errno=RET.OK, errmsg=“操作成功”)
return jsonify(errno=RET.OK, errmsg=“操作成功”)
回复的显示:
回复
收藏如何显示:
如果用户没有登录,那么显示"收藏"图标。
user = g.user
if not user
?笔记:这里候的显示,并没有用到ajax,只是模板的渲染。只是通过模板传一个标志过去,然后通过这个二分法的标志,渲染成"收藏",还是"已收藏"图标。
?笔记:这里不能用ajax,只能用模板的{% if is_collect = Ture%}block{% else %}none{% endif %}
如果用户登录,
如果收藏了,那么显示"已收藏图标"
如果没收藏,那么显示"收藏"
评论框:
if user
那么显示用户头像
if not user
则只显示输入框,评论
前端:
![用户图标](../images/cat.jpg)
?笔记:
显示下面的几条评论
{{ data.news.comments_count }}条评论
###显示下面的评论:
评论用户的头像,昵称,评论创建时间 ,回复的图标,赞的图标
先看前端提供的代码:
###{% if comment.parent %}
评论下面的回复
加上 new_id,commend_id属性。
###评论下面的点赞
赞
这条评论的点赞数:
commend.like_count
{% if comment.like_count > 0 %}
{{ comment.like_count }}
{% else %}
赞
{% endif %}
p
实现点赞的后端逻辑:
ajax实现:
// 收藏
$(“.comment_up”).click(function () {
var params = {
"news_id": $(this).attr('data-newid'),
"likecount": $(this).attr('data-likecount'),
"comment_id": $(this).attr('data-commentid'),
}
$.ajax({
url: “/comment_like”,
type: “post”,
contentType: “application/json”,
headers: {
“X-CSRFToken”: getCookie(“csrf_token”)
},
data: JSON.stringify(params),
success: function (resp) {
if (resp.errno == “0”) {
// 收藏成功
// 隐藏收藏按钮
$(“.collection”).hide(); ?问题:如何后端处理成功,那么点赞数comment.like_count+1。那么如何返回这个变量呢,直接操作它的文本,让文本数加1。那点赞如果是再点一次呢?这就跟用户有关了,如果一个用户点赞两次,那么就是取消。用什么来区别呢??笔记:在javascript通过class has_comment_up来判断。如果有值,那么ajax就传action = remove。后端根据不同的参数来处理。不光后端,ajax也根据action来不同处理,如果action=remove,那么移除它的属性,并且把它的值减1。
// 显示取消收藏按钮
$(“.collected”).show();
}else if (resp.errno == “4101”){
$(‘.login_form_con’).show();
}else{
alert(resp.errmsg);
}
######点赞的后端实现:
在后端要做哪些呢?
评论多个赞
@news_blu.route(‘/news_collect’, methods=[“POST”])
@user_login_data
def collect_news():
“”"
收藏新闻
1. 接受参数
2. 判断参数
3. 查询新闻,并判断新闻是否存在
:return:
“”"
user = g.user
if not user:
return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
# 1. 接受参数
comment_id = request.json.get("comment_id")
action = request.json.get("action")
# 2. 判断参数
if not all([comment_id, action]):
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
if action not in ["add", "remove"]:
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
try:
news_id = int(comment_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
if action = add:
comment_like = CommentLike()
comment_like.user_id = user.id
comment_like.comment_id = comment_id(?笔记:这里写错了,前面应该根据表单传过来的comment_id拿到comment,然后:comment_like.comment_id = comment_id
comment_like.save()(django)
comment_like.save()
db.session.commit()
else:
# 取消点赞评论
comment_like_model = CommentLike.query.filter(CommentLike.user_id == user.id,
CommentLike.comment_id == comment.id).first()
if comment_like_model:
db.session.delete(comment_like_model)
# 更新点赞次数
comment.like_count -= 1
try:
db.session.commit()
except Exception as e:
db.session.rollback()
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="数据库操作失败")
return jsonify(errno=RET.OK, errmsg="OK")
try:
db.session.commit()
except Exception as e:
db.session.rollback()
current_app.logger.error(e)
return jsonfy()
return jsonify(errno=RET.OK, errmsg="操作成功")
?笔记 ?经验:收藏和点赞,ajax,的处理。都要先判断 返回是0,再判断是否有用户没登录的情况,最后所有的情况,都输出:alert(resp.errmsg)
写好了前端,再根据ajax写后端的逻辑。
现在写回复的前端javascript,和后端逻辑:
点了回复,那么就在下面加上一条评论记录。
数据库操作:
增加一条评论,
commments = Comment()
comments.user_id = user.id
comments.news_id = news.id
comments.content =
?笔记:除了拼接html内容,还要清空输入框,更新评论数。
$(“.comment_list_con”).prepend(comment_html)
// 让comment_sub 失去焦点
$(‘.comment_sub’).blur();
// 清空输入框内容
$(“.comment_input”).val(“”)
updateCommentCount()
}else {
alert(resp.errmsg)
?笔记:
从前端拿到数据,是要操作元素的属性的。
var news_id = $(this).attr(‘data-newsid’)
var news_comment = $(“.comment_input”).val();
再根据javascript,写出后端。
def comment():
拿到数据
有效性
数据库处理
返回给ajax,其它错误,0,还有一个user
user不用判断,如果没user,不可能提交
news_id = request.json.get(“news_id”)
content = request.json.get(“content”)
if not all[news_id, content]:
return jsonfy(errno:PARAMERA,errmsg:“参数错误”)
?问题,这里写什么错误呢?数据有效性错误是哪个
### 数据库处理
news = News.query.get(news.id = news_id)
comment = Comment()
comment.news_id = news.id
comment.user_id = user.id
comment.content = content
db.add(comment)
try:
db.session.commt
except:
?如何把comment的内容返回给json,看下面
return jsonify(errno=RET.OK, errmsg="OK", data=comment.to_dict())
返回给ajax一个字典,ajax可以拿着这个字典去造一个新的评论html,方法跟模板差不多。然后拼接到之前的标签之上,用
$(".comment_list_con").prepend(comment_html)
现在写文章作者右上角那块的前端代码
<div class="author_card">
<a href="#" class="author_pic"><img src="../images/user_pic.png" alt="author_pic"></a>
<a href="#" class="author_name">张大山</a>
<div class="author_resume">张大山的简介,张大山</div>
<div class="writings"><span>总篇数</span><b>23</b></div>
<div class="follows"><span>粉丝</span><b>36</b></div>
<a href="javascript:;" class="focus fr">关注</a>
<a href="javascript:;" class="focused fr"><span class="out">已关注</span><span class="over">取消关注</span></a>
</div>
详情页加载时显示,
根据文章拿到作者,再拿到作者的头像,昵称,签名,发布的文章数,粉丝数,
一开始的关注图标,像收藏图标,在详情页就要判断,是关注状态还是未关注状态。
data.news.author.avat…,data.news.author.news_count,data.news.author.follows_count。
如果关注了,那么显示已关注 {% if data.news.author in user.followers%}block{% else %}none{% endif%}
?笔记:上面这段逻辑放在后端,给前端传递一个二分法标志就行,如果is_followed。如下:
is_followed = False # if 当前新闻有作者,并且 当前登录用户已关注过这个用户
if news.user and user:
# if user 是否关注过 news.user
if news.user in user.followed:
is_followed = True
data = {
"user": user.to_dict() if user else None,
"news_dict_li": news_dict_li,
"news": news.to_dict(),
"is_collected": is_collected,
"is_followed": is_followed,
"comments": comment_dict_li
}
而且:我上面写user.follower。是不对的。应该写成:user.followed。
现在开始写关注那一块的ajax以及后端:
后端:
这个用户成了这篇文章作者的一个粉丝
author = User.query.filter(User.news_id = news_id)
author.followers.append(user)
?经验:写ajax。1先是否需要写两个,比如关注和取消关注,两个action不同,写两个ajax,后端逻辑写一个,在里面用if做判断区分就行了 2自己先玩一下前端,看点了之后会有哪几块变化,像关注作者有两块,一块是关注变取消关注。一块是粉丝数加或减1。而评论提交却有三块变化。
用户中心模块
用户中心模块,跟简书比,简书可以创建自己的专题,别人的文章 也可以收藏到自己的专题。在个人中心也有专题列表。个人中心还有收获了别人多少喜欢,还能统计自己写的字数。写文章模块,简书里是重新开一个新的窗口标签。
######先做用户中心前端。
1拿到前端提供的页面。
2加上后端要替换的东西,好像只有用户要用到数据库东西。其它标签只是要注意,里面要放些什么属性,比如点这个标签,你要向后端传些什么数据。不要传什么数据。且用户中心全是user = g.user的内容。相对取数据很简单。
#####新闻发布,点发布跳转到新闻列表,这个如何实现?这个是表单提交?但是没有
?笔记 ?经验:调试的时候,如果打断点进不了,就要看前端代码是否有问题?
######现在写个人中心新闻列表的前端代码:
如果是通过的,那么可以进入详情页
如果是未通过,那么显示理由
如果在审核,那么点不进去
user = g.user
{% for news in user.news_list.to_dict %}
- {% if {{ news.status }}=0%}{{news.title}}通过{% elsif %}
- news.title审核中{{ news.create_time}}}
- {% else %}
- 智能音箱“不智能”:这次轮到三星语音助手Bixby被吐槽了 未通过 2018-1-17 {{ news.reason }}
- {% endfor %}
######现在写新闻列表的后端:
/news/news_list
def newslist():
user = g.user
news_list = user.news_list
data = {
news_list:news_list
}
return template(user_news_list.html data)
? 分页的还是没有太搞明白:参考:
https://www.jianshu.com/p/a68d4e6a20d1现在做新闻发布前端:
点新闻发布,用模板渲染的方式,先做模板,再写函数
?问题,下面什么意思?
?笔记:我以为前端不用传参数,其实分类要传。
######后端:
后端和提交表单放在一个函数中,用GET,POST区分。
返回数据用ajax,返回的是?跳转到新闻列表页。
?问题:前端的话,如何用ajax实现跳转?
也可以用表单实现
?笔记:ajax可以用url:来找到后端的函数处理逻辑,那么表单用什么呢?用标签?前端ajax:
后端:
接收参数
有效性检验
数据库处理
news = News()
news.title = title
…
news.user_id = user.id
News.add(news)
db.session.save
返回josnfy
return josnfy(errno = 0 ,errmsg = “参数错误”)$(“.release_form”).submit(function (e) {
e.preventDefault()var signature = $(“#title”).val()
var nick_name = $(“#cataloge_id”).val()
var gender = $(“digest”).val()
var gender = $(“index_image”).val()
var gender = $(“content”).val()// 修改用户信息接口
var params = {
“signature”: signature,
“nick_name”: nick_name,
“gender”: gender
}$.ajax({
url: “/profile/news_release”,
type: “post”,
contentType: “application/json”,
headers: {
“X-CSRFToken”: getCookie(“csrf_token”)
},
data: JSON.stringify(params),
success: function (resp) {
if (resp.errno == “0”) {
//跳转到新闻列表页
?问题:这个怎么实现?
}else {
alert(resp.errmsg)
}
}#####后端实现:
?笔记:?经验:如果前端页面的form表单标签里,有Name属性,它会自动提交,在后端就可以通过表单直接获取,而不需要在ajax中获取。用request.form.get。
?思想:这节讲新闻发布的课可以去听下,如果通过bug,一步步修改代码。这是什么东西呢?我也不知道