文章页面设计

之前已经完成了列表以及md文档的读取, 现在把文章放上去再加上评论.点赞,就可以 了

先完成md文档的展示

直接将之前这里使用markdown转化为html的文档传进去就行

view.py
    html_content = markdown2.markdown(md_content,extras=['tables', 'fenced-code-blocks', 'strike', 'footnotes', 'cuddled-lists','wiki-tables', 'pyshell'])
    #这里多添加点额外功能,文章就能显示表格,脚注,代码块等功能了
    return render(request, 'article.html', {'iframe': html_content})
article.html
<main class="markdown" style="margin: 0 auto;width: 80vw">
    {{ iframe|safe }}
</main>
##其实这里可以对body使用padding会更方便

这里就不截图了,正如看到的那样(

然后添加文章标题,评论和点赞功能
#标题可以直接用网页标题解决
{{request.GET.pid}}

下面是点赞功能,先获取数据库的数据

from django.shortcuts import get_object_or_404
    obj = get_object_or_404(Post, text=pid, parent__isnull=True)
    detail = {
        'author':obj.author,
        'likes':obj.likes,
        'comments_count':obj.comments_count,
        'created_at':obj.created_at,
        'parent':obj.parent,
    }
    return render(request, 'article.html', {'iframe': html_content,'detail':detail})

可以展示点赞数,作者,评论数,发布日期了,接下来实现点赞功能,使用ajax请求

这里先修改一下之前的模型,之前使用likes统计点赞数,却不知道是那个用户点击的,这会导致重复点击和无法查看用户点赞的内容, 也无法取消点击.这里使用django的多对多字段,本质是建立一个新的表,包括用户ID和文章ID字段,这样可以方便之后对点赞的列表进行筛选,

    likes = models.ManyToManyField(User, related_name='liked', blank=True)  # 使用ManyToManyField记录点赞的用户
    def like_count(self):
    	return self.likes.count()
    #以及统计点赞数
<div>
    <p>点赞数: {{ detail.like_count }}</p>
    <!-- 点赞按钮 -->
    <button id="like-button" onclick="likeArticle()">点赞</button>
</div>
 
<script>
           fetch("{% url 'add_like' detail.id %}", {
            method: 'POST',
            headers: {
                'X-CSRFToken': '{{ csrf_token }}',
                'Content-Type': 'application/json'
            },
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                // 更新点赞数
                document.getElementById('like-count').innerText = ` ${data.likes_count}`;
 
                // 更新按钮文本
                if (data.action === 'liked') {
                    document.getElementById('like-button').innerText = '取消点赞';
                } else if (data.action === 'unliked') {
                    document.getElementById('like-button').innerText = '点赞';
                }
            }
        })
        .catch(error => {
            console.error('点赞失败:', error);
        });
    }

添加路由

url.py
path('article/<int:detail_id>/like/', views.add_like, name='add_like'),

视图函数

@require_POST
def add_like(request, detail_id):
    user = request.user
    # 获取对应文章
    obj =Post.objects.get(id=detail_id)
    
    # 更新点赞数
    if obj.likes.filter(id=user.id).exists():
        # 用户已经点赞,执行取消点赞
        obj.likes.remove(user)
        action = 'unliked'
    else:
        # 用户未点赞,执行点赞
        obj.likes.add(user)
        action = 'liked'
    
    # 返回JSON响应,更新前端点赞数
    return JsonResponse({'success': True, 'likes_count': obj.like_count, 'action': action})

评论数和评论功能同样使用ajax给通过data调用