ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

博客项目——〇四 个文章页面设计

2020-06-21 11:07:30  阅读:293  来源: 互联网

标签:up 博客 pk user 文章 article div id 页面


下面我们来做一下显示文章内容的页面。先分析一下博客园页面布局是怎么样的

页面布局

 刨去一些细节上的内容我们先不管,大概整体布局是这样的

 

 其实整体效果也可以使用上一章节里的基础母版,只做page-main这个block就可以了

文章内容

在这个页面中 文章的获取其实还是比较简单的,我们先看一看这个文章内容是怎么获取的

因为在我们可以直接通过url访问一篇文章,这种是最直接的访问方法,其他用a标签的访问也相当于这个方式。我们看一下这个url的结构

https://www.cnblogs.com/yinsedeyinse/p/13052827.html

也就是用户/文章/文章id的形式,所以我们对url的定义就是这样的

url(r'(\w+)/article/(\d+)/$',views.article_detial), 

正则匹配的的一个字段就是username,这个用户名是被访问blog站点的作者,不是登录的用户;第二个字段用了\d,也就是说文章id都是以数字形式存在的。直接匹配数字就可以了。 

ORM流程

article = models.Article.objects.filter(pk=1).first()                #获取id=1的article对象

text = article.articledetail.content

我们的article表和articledetail是通过一个外键关联的,用上面的方法就可以拿到文章里的内容。

内容的渲染

有一点要注意的,因为我们在编辑文章内容时是带有一定样式的,其实我们在数据库里存的应该都是html样式的字符串,如果要把这些字符串按要求的标签样式显示出来,就要记得在渲染的时候用safe这个tag

<div>
    <h1>{{article.title}}</h1>
    <p>{{article.articledetail.content|safe}}</p>
</div>

这样就可以显示出我们需要的效果(可以直接从博客园里复制一片文章的div到数据库里,然后显示出来)。

点赞功能

下面是这一章第一个重要的地方:点赞。我们可以注意一下,在一般的网页中的点赞和踩都是局部刷新的,也就是用AJAX的方法实现的。我们下面一步步把这个效果实现出来

前端的构造(DIV)

简单的操作,我们把博客园里的点赞部分可以直接超过来

 

 复制的时候要注意把图片和样式一并拿到。

整个div是这样的

<!-- 点赞踩灭开始 -->
<div id="div_digg">
    <div class="diggit action">
        <span class="diggnum" id="digg_count">{{article.up_count}}</span>
    </div>
    <div class="buryit action">
        <span class="burynum" id="bury_count">{{article.down_count}}</span>
    </div>
    <div class="clear"></div>
    <div class="diggword" id="digg_tips">
    </div>
    <div class="clear"></div>

    <div class="diggword" id="digg_tips" style="color: red;"></div>
</div>
<!-- 点赞踩灭结束 -->

 article就是我们在视图中通过id获得的article对象,里面包含了赞和踩的数量

在这里因为赞和踩的流程是一样的,所以直接对action这个div做了一个点击事件然后关联了一个AJAX请求

 1 <script>
 2     $('#div_digg .action').click(function(){
 3 
 4         // 把点赞和踩灭放在一个function内,通过div的属性是否有diggit判定点击的是点赞还是踩灭
 5         var is_up = $(this).hasClass('diggit');
 6         var article_id = "{{article.pk}}";  //一定要注意在js内的模板替换字符串要用引号括起来
 7         var btn = $(this);
 8         console.log(article_id)
 9         $.ajax({
10             url:"blog/up_down/",
11             type:"POST",
12             data:{
13                 csrfmiddlewaretoken:'{{csrf_token}}',
14                 is_up:is_up,
15                 article_pk:article_id
16                 },
17 
18             success:function(data){
19                 console.log(data)
20                 if(data.state)
21                 {
22                 btn.text(parseInt(btn.text())+1);
23                 
24                 }
25                 else
26                 {
27                 $('#digg_tips').text(data.msg);
28                 }
29                 
30                 }
31             })
32         })
33 </script>

可以注意一下思路,我们在点击了一个div以后判定一下里面有没有一个diggit属性(is_up),如果有点击的就是赞,否则就是踩。AJAX携带的数据里只有一个is_up和一个当前文章的id,再看一下Ajax请求对应的视图

 1 from django.db.models import F
 2 import json
 3 def up_down(request):
 4     print('in up_down')
 5     ret={'state':False}
 6 
 7     article_pk = request.POST.get('article_pk')
 8     #因为用get方法得到的is_up为一个为true的字符串,我们写到数据库里的必须为一个布尔量,要用json反序列话一下
 9     is_up = json.loads(request.POST.get('is_up'))  
10 
11     user = request.user
12     article = models.Article.objects.get(pk=article_pk)
13 
14     if not user:
15         ret['msg'] = '请登录'
16     else:
17         try:
18             models.ArticleUpDown.objects.create(user=user,article = article,is_up=is_up)
19             models.Article.objects.filter(pk=article_pk).update(up_count=F('up_count')+1)
20             ret['state'] = True
21         
22         except Exception as e:
23             ret1 = models.ArticleUpDown.objects.get(user=user,article=article).is_up
24             ret['msg'] = '已经赞过' if ret1 else "已经踩过"
25 
26     return JsonResponse(ret)

整个流程还算清晰,还是有几点需要注意的

1.通过request.POST.get()拿到的值是个字符串类型的数据(string),但是ArticleUpDown这个表里的is_up字段是个布尔量类型的数据,那么就不能直接写,就要用JSON反序列化一下。

2.常规情况下在没登录的时候是不能点赞或踩灭的,所以要对request.user进行判断,看看当前是否有用户登录,但是未有用户登录是还是有user值的,只不过登录状态为anonymoususer,我们可以用下面的方式来判定用户登录的状态

user.is_authenticated

如果有正常用户登录,返回值就为True,否则就为False。

3.ORM添加新数据的时候是先对UpDown表里添加数据,成功了以后再对Article表里添加赞或踩的数量,这里用到了一个F查询,忘记的话可以查一下以前的博客(点击查看)。如果操作成功的话就返回一个成功对应的状态字。

4.因为最后显示赞的数量是通过ajax实现的,我们没有重新从数据库里拿数,只是做了个DOM操作。但是操作前还是要做一下判断,看看前面的ORM操作是否成功。

5.实际情况中还有一个使用环境:自己是无法对自己的文章操作的。还应该加一个对作者和登录的用户名进行一下比对。但这里没有做,最后的视图代码中应该会有

JS代码的静态文件

我们前面的所有操作都是把js代码放在html文件中,但是这样操作不利于代码的复用。可是如果把这段代码放在一个js文件中,有些参数是需要render渲染的,还有一些标签的关联是怎么操作的呢?这时就需要把上面那段JS代码重构一下了。

注意render函数的过程,是把整个HTML文件过一遍,对render函数来说,HTML文件就是一个字符串,函数在执行的过程中一遇到{{}}和{%%}的时候就把中间的字符串直接把参数中的字典里的数据套进去。但是导入的JavaScript标签

<script src="/static/js/updown.js"></script>

就直接按照字符串的形式过一遍,并不会把JavaScript文件里的{{}}替换掉

我们把前面整个JavaScript代码段粘贴到一个新的js文件中,要改的地方有两点,也就是两个{{}}的地方

1.现在这种csrf的方式不行,必须在HTML文件中通过下面的代码生成一个隐藏的div

{%csrf_token%}

然后把js中csrf中间件的部分修改成下面这样的

csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),

2.在这个js文件中获取article_id的方法是这样的

var article_id = "{{article.pk}}";  //一定要注意在js内的模板替换字符串要用引号括起来

这里讲的是一个比较笨的方法:在html中直接做一个div,把需要的内容加到div的属性里,div可以隐藏,不过因为div里没有内容隐藏不隐藏关系不大

<div class="info" article_id='{{article.nid}}' style="display:none ;"></div>

然后在js中直接用attr获取属性就可以了

var article_id = $('.info').attr('article_id');

其他就不用改了。

评论功能

 评论功能的实现比较复杂,我们在下一章详细来说。

 

标签:up,博客,pk,user,文章,article,div,id,页面
来源: https://www.cnblogs.com/yinsedeyinse/p/13170841.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有