Django推荐相似文章

一 点睛

在发布文章时,给每篇文章都设置了文章标签,在这个功能的基础上,可以向阅读某篇文章的用户推荐与该文章相似的文章。有同样标签的文章应该是相似的,并且假设用户想阅读相似的文章,于是就有了推荐相似文章的开发需求。

二 编写视图函数mysite/article/list_views.py

# 没有登录的用户也可以访问这个函数
def article_detail(request, id, slug):
    article = get_object_or_404(ArticlePost, id=id, slug=slug)
    # total_views:记录文章访问量
    # 一般通过“对象类型:对象ID:对象属性”来命名一个键
    total_views = r.incr("article:{}:views".format(article.id))
    # zincrby的原型是zincrby(name,amount,value):根据amount所设定的步长值增加有序集合(name)中的value的数值
    # 实现了article_ranking中的article.id以步长1自增,
    # 即文章访问一次,article_ranking就将文章id的值增1
    r.zincrby('article_ranking', 1,article.id)
    # 得到article_ranking中排序前10名对象
    article_ranking = r.zrange('article_ranking', 0, -1, desc=True)[:10]

    # 得到前10名文章ID
    article_ranking_ids = [int(id) for id in article_ranking]

    # 查询出id在article_ranking_ids这个范围内的所有文章对象,并以文章对象为元素生成列表
    most_viewed = list(ArticlePost.objects.filter(id__in=article_ranking_ids))

    # 对所得到的列表进行排序
    most_viewed.sort(key=lambda x: article_ranking_ids.index(x.id))

    if request.method == "POST":
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            new_comment = comment_form.save(commit=False)
            new_comment.article = article
            new_comment.save()
    else:
        comment_form = CommentForm()

    # 得到当前文章的所有标签在数据库表中的id
    article_tags_ids = article.article_tag.values_list("id", flat=True)
    # 得到所有与当前文章有共同文章标签的文章对象,并排除文章本身
    similar_articles = ArticlePost.objects.filter(article_tag__in=article_tags_ids).exclude(id=article.id)
    # 对于相似文章,根据与当前文章相同的标签数量进行标注,然后以相同标签数量和文章发布时间为关键词排序
    similar_articles = similar_articles.annotate(same_tags=Count("article_tag")).order_by('-same_tags', '-created')[:4]

    # 将访问次数传递给模板,将最受欢迎文章列表传递给前端
    return render(request, "article/list/article_detail.html",
                  {"article": article, "total_views": total_views,"most_viewed": most_viewed,"comment_form":comment_form,"similar_articles":similar_articles})

三 编写模板

{% extends "base.html" %}
{% load staticfiles %}
{% load article_tags %}
{% block title %}{{ article.title }}{% endblock %}
{% block content %}
<!-- with发起一个赋值操作,它的结尾部分是endwith,total_likes分别为点赞用户总数,total_likes在
这两部分圈定的范围内有效-->
{% with total_likes=article.users_like.count users_like=article.users_like.all %}

<div class="container">
    <div class="col-md-9">
        <header>
            <h1>{{ article.title }}</h1>
            <p>
                <a href="{% url 'article:author_articles' article.author.username %}">
                    {{ article.author.username }}
                </a>
                <!-- pluralize的作用:如果total_likes为0或复数,则显示的是likes,如果total_likes为1,则显示like-->
                <span style="margin-left:20px" class="glyphicon glyphicon-thumbs-up">{{ total_likes }}like{{ total_likes | pluralize }}</span>
                <!-- 该文章总的访问此时-->
                <span style="margin-left: 20px">{{ total_views }}view{{ total_views | pluralize }}</span>
            </p>
            <!--标签功能-->
            <p> <span style="margin-right: 10px"><strong>标签:</strong></span> {{ article.article_tag.all | join:", "}}</p>
        </header>

        <link rel="stylesheet" href="{% static 'editor/css/editormd.preview.css' %}"/>
        <div id='editormd-view'>
        <!--<textarea id="append-test" style="display:none;">-->
<!--{{ article.body }}-->
        <!--</textarea>-->
<!--使用自定的过滤器markdown-->
{{ article.body | markdown }}
        </div>
        <div>
            <!--点赞功能实现-->
            <p class="text-center">
                <a onclick="like_article({{article.id}}, 'like')" href="#"><span class="glyphicon glyphicon-thumbs-up">like</span></a>
                <a onclick="like_article({{article.id}}, 'unlike')" href="#"><span style="margin-left: 15px;"
                                                                                   class="glyphicon glyphicon-thumbs-down">unlike</span></a>
            </p>
        </div>
        <div>
            <p class="text-center"><strong>点赞本文的读者</strong></p>
            {% for user in article.users_like.all %}
            <p class="text-center">{{ user.username }}</p>
            {% empty %}
            <p class="text-center">还没有人对此文章表态</p>
            {% endfor %}
        </div>
        <!--以下是评论功能-->
        <hr>
        <div>
            <h3><span class="glyphicon glyphicon-bullhorn"></span>本文有{{ article.comments.count }}评论</h3>
            {% for comment in article.comments.all %}
            <div>
                <p><strong>{{ comment.commentator }}</strong>说:</p>
                <p style="margin-left:40px;">{{ comment.body }}</p>
            </div>
            {% empty %}
            <p>没有评论</p>
            {% endfor %}

            <h3><span class="glyphicon glyphicon-send"></span>看文章,发评论,不要沉默</h3>
            <form action="." method="post" class="form-horizontal" role="form">{% csrf_token %}
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label">评论员</label>
                    <div class="col-sm-10">
                        {{ comment_form.commentator}}
                    </div>
                </div>
                <div class="form-group">
                    <label for="inputEmail3" class="col-sm-2 control-label">评论</label>
                    <div class="col-sm-10">
                        {{ comment_form.body }}
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <p><input type="submit" name="" value="发评论" class="btn btn-primary"></p>
                    </div>
                </div>
            </form>
        </div>
    </div>
    <div class="col-md-3">
        <p class="text-center">
        <h3>最受欢迎文章</h3></p>
        <ol>
            {% for article_rank in most_viewed %}
            <li>
                <a href="{{article_rank.get_url_path}}">{{ article_rank.title }}</a>
            </li>
            {% endfor %}
        </ol>
        <hr>
        <p class="text-center">
        <h3>最新文章</h3></p>
        <div>{% latest_articles 4 %}</div>
        <hr>
        <p class="text-center">
        <h3>最多评论文章</h3></p>
        <!--把自定义标签所得到的对象赋值给一个变量most_comments-->
        {% most_commented_articles as most_comments %}
        <div>
            <ul>
                {% for comment_article in most_comments %}
                <li>
                    <a href="{{comment_article.get_url_path}}">{{ comment_article.title }}</a>
                </li>
                {% endfor %}
            </ul>
        </div>

        <hr>
        <p class="text-center">
        <h3>推荐相似文章</h3></p>
        <div>
            {% for similar in similar_articles %}
            <p><a href="{{ similar.get_url_path }}">{{ similar.title }}</a></p>
            {% empty %}
            <p>对不起, 没有相似文章</p>
            {% endfor %}
        </div>
    </div>
</div>
<script src='{% static "js/jquery.js" %}'></script>
<script src='{% static "editor/lib/marked.min.js" %}'></script>
<script src='{% static "editor/lib/prettify.min.js" %}'></script>
<script src='{% static "editor/lib/raphael.min.js" %}'></script>
<script src='{% static "editor/lib/underscore.min.js" %}'></script>
<script src='{% static "editor/lib/sequence-diagram.min.js" %}'></script>
<script src='{% static "editor/lib/flowchart.min.js" %}''></script>
<script src='{% static "editor/lib/jquery.flowchart.min.js" %}'></script>
<script src='{% static "editor/editormd.js" %}'></script>
<script type="text/javascript" src="{% static 'js/layer.js'%}"></script>
<script type="text/javascript">
$(function(){
    editormd.markdownToHTML("editormd-view", {
        htmlDecode      : "style,script,iframe",  // you can filter tags decode
        emoji           : true,
        taskList        : true,
        tex             : true,  // 默认不解析
        flowChart       : true,  // 默认不解析
        sequenceDiagram : true,  // 默认不解析
    });
});
function like_article(id,action){
    $.ajax({
        url: "{% url 'article:like_article' %}",
        type: "POST",
        data: {"id":id, "action":action},
        success: function(e){
            if(e=="1"){
                layer.msg("感谢点赞");
                window.location.reload();
            }else{
                layer.msg("我会继续努力");
                window.location.reload();
            }
        },
    });
}
</script>
{% endwith %}
{% endblock %}

四 测试

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django是一个流行的开源Python Web框架,可以用于快速开发高效稳定的Web应用程序。推荐系统是一种根据用户的兴趣和行为,为其提供个性化推荐内容的技术。 在开发推荐系统时,Django提供了丰富的功能和工具,使得开发变得简单而高效。首先,Django提供了强大的ORM(对象关系映射)功能,可以方便地与数据库交互,存储和管理用户数据和推荐结果。这使得开发者可以轻松地构建数据模型,记录用户的兴趣和行为。 其次,Django具有灵活的视图和模板系统,使得开发推荐系统的前端界面变得简单直观。开发者可以使用Django的模板语言和表单功能来设计用户界面,展示推荐内容和接收用户反馈。 另外,Django还提供了强大的缓存机制,可以有效地处理大规模的数据计算和推荐工作。通过使用Django的缓存系统,开发者可以优化数据查询和计算过程,提高推荐系统的性能和响应速度。 此外,Django的安全性能也是推荐系统开发的重要考虑因素之一。Django提供了丰富的安全功能,包括用户认证和授权机制、防止跨站点请求伪造(CSRF)攻击等。这些安全功能使得开发者可以确保用户数据和推荐结果的隐私和安全。 总之,Django作为一个强大的Web框架,在推荐系统的开发中具有很大的优势。它提供了丰富的功能和工具,使得开发者可以方便地构建个性化推荐系统,并提供高效稳定的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值