代码改变世界

135-使用django实现点赞功能

2020-09-06 22:30  lzhshn  阅读(1381)  评论(0编辑  收藏  举报

大前提:点赞并不设计表单提交,在模板里已经有某个表单的情况下,点赞本身不需要使用表单来实现,而且可以说非常不推荐表单来实现。

我的点赞逻辑是:一个id对一篇文章只能点赞一次,自己不能对自己点赞。

 

【1】视图函数。除了显示必然的内容之外,还需要传递一个关于点赞的重要变量:

# 注意:一定是从首页点击进去的
# 为了避免直接在url里改编号,显示其他内容,还必须加上开放判断
@login_required
def op_one_note(request, pk):
    current_user = request.user
    pk_note = get_object_or_404(MyNote, open_bool=True, id=pk)
    if request.method != 'POST':
        comment_form = CommentForm()
        note_all_comment = pk_note.comment_note.all().order_by('-add_time')
        if_praise = Praise.objects.filter(note=pk_note.title, user=current_user.username).exists()
        # print(if_praise)
        context = {'pk_note': pk_note, 'note_all_comment': note_all_comment, 'comment_form': comment_form,
                   'if_praise': if_praise}
        return render(request, 'op_one_note.html', context)

    else:
        form = CommentForm(request.POST)
        if form.is_valid():
            new_comment = form.save(commit=False)
            new_comment.relation_note = pk_note
            new_comment.author = current_user.username
            new_comment.save()
            pk_note.comment_num += 1
            pk_note.save()
            return HttpResponseRedirect(reverse('notebook:op_one_note', args=[pk]))

 

这里有一个非常关键的表达式:

if_praise = Praise.objects.filter(note=pk_note.title, user=current_user.username).exists()

这个地方用来判断:在所有已经存储的点赞记录里,是否有文章和用户名已经存在的模型。为什么这么做?先请记住:if_praise

 

【2】点赞的类。下面看一下如何定义的:点赞类包括3个属性:文章,用户,时间。

class Praise(models.Model):
    note = models.CharField(max_length=512, blank=True, null=True)
    user = models.CharField(max_length=256, blank=True, null=True)
    time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.note, 'by', self.user

 

 

【3】模板,介绍一下如何实现点赞:

        {# add a praise #}
        <div id="praise">
            {% if request.user.username != pk_note.author %}
                {% if if_praise %}
                    <p>already praise!</p>
                {% else %}
                    <a href="{% url 'notebook:get_praise' pk_note.pk %} ">praise!</a>
                {%endif %}
            {% endif %}
        </div>

 

这里很明确:只有当前用户不等于这篇文章的作者时,才能进行点赞相关判断。接着,如果之前提到的那个if_praise为真,表明已经点过赞了,此时不能操作仅提示,如果为假,则使用一个“链接”来完成点赞。

链接指向一个函数,并传递当前note的pk值。

 

【4】函数。用一个函数对点赞模型进行存储,然后重定向到当前页面。

def get_praise(request, pk):
    current_user = request.user
    pk_note = get_object_or_404(MyNote, open_bool=True, id=pk)
    new_praise = Praise()
    new_praise.note = pk_note.title
    new_praise.user = current_user.username
    new_praise.save()
    pk_note.praise_count += 1
    pk_note.save()
    return HttpResponseRedirect(reverse('notebook:op_one_note', args=[pk]))

 

这个函数照例要先获取当前的用户和文章,然后对点赞模型进行存储,然后将点赞数+1,再对文章模型进行存储。最后就是重定向,重新打开这个页面,并再一次判断点赞情况。

 

这就是点赞的实现,是不是很简单,还思路清晰!!!