• Django 利用管理器实现文章归档


    Django管理器:class Manager

           管理器是Django的模型进行数据库查询的接口,Django应用的每个模型都拥有至少一个管理器。默认情况下,Django为每个模型类添加一个名为objects的管理器,然而如果要将objects用于字段名称或想使用其他名称而不是objects来访问管理器,可在每个模型类中重命名他们。自定义的管理器方法可以返回你想要的任何数据,而不需要返回一个查询集。eg: models.py

    # 文章模型
    class Article(models.Model):
        title = models.CharField(max_length=50, verbose_name='文章标题')
        desc = models.CharField(max_length=50, verbose_name='文章描述')
        content = models.TextField(verbose_name='文章内容')
        click_count = models.IntegerField(default=0, verbose_name='点击次数')
        is_recommend = models.BooleanField(default=False, verbose_name='是否推荐')
        date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
        user = models.ForeignKey(User, verbose_name='用户')
        category = models.ForeignKey(Category, blank=True, null=True, verbose_name='分类')
        tag = models.ManyToManyField(Tag, verbose_name='标签')
        objects = ArticleManager()  # 在模型中使用自定义的管理器
    
    

    要实现文章归档,需要根据日期对文章这个模型类进行筛选:我们的目的是根据 ‘年-月’来归并所有文章,此外若 17年8月没有文章,则归档也不显示17年8月这一空白归档。类似如下:

                

    为实现根据年-月的文章筛选,可以早models.py中建立一个文章管理器,继承自models.Manager:

    class ArticleManager(models.Manager):
        def distinct_date(self):  # 该管理器定义了一个distinct_date方法,目的是找出所有的不同日期
            distinct_date_list = []  # 建立一个列表用来存放不同的日期 年-月
            date_list = self.values('date_publish')  # 根据文章字段date_publish找出所有文章的发布时间
            for date in date_list:  # 对所有日期进行遍历,当然这里会有许多日期是重复的,目的就是找出多少种日期
                date = date['date_publish'].strftime('%Y/%m 存档') # 取出一个日期改格式为 ‘xxx年/xxx月 存档’
                if date not in distinct_date_list:
                    distinct_date_list.append(date)
            return distinct_date_list

    上文代码建立的管理器需要在文章模型类加上语句:objects = ArticleManager()  ,然后就可以调用 distinct_date 方法了: archive_list = Article.objects.distinct_date(),对比:

    article_list = Article.objects.all() # 获取所有文章,获取到的是所有文章对象的一个列表

    archive_list = Article.objects.distinct_date() # 文章归档 获取到的列表格式为: xxx年/xxx月 存档

    我们要将 archive_list 这个列表显示在html页面中,所有需要一个for循环:在base.html中加入:

    <div class="tuwen">
          <h3>文章归档</h3>
          <ul>
            {% for archive in archive_list %}
            <li>
              <p><span class="tutime font-size-18"><a href='{% url 'archive' %}?year={{ archive | slice:":4" }}&month={{ archive | slice:"5:7" }}'>{{ archive }}</a></span></p>
            </li>
            {% endfor %}
          </ul>
        </div>

     左图即为html中的结果。  这里 {% url %} 这个模板标签的作用是解析视图函数对应的 URL 模式, 那么上文代码中 ‘{% url 'archive' %}’ 是指解析views.py 中视图函数archive对应的url模式。那么,每行归档文字都有了一个链接,格式为: http://127.0.0.1:8000/archive/?year=2015&month=02,{% url %}解析时会将year=2015和month=02 这两个参数值传递到 views.py 请求中。 综上,至此我们只实现了在base主页面上显示左图,并且为各个归档赋予了链接,下一步我们需要为这个链接编写相应的操作。

    编写urls.py 和 views.py

    回顾上文的链接http://127.0.0.1:8000/archive/?year=2015&month=02, 我们看到链接为 archive, 所以需要对应的urls 和 视图函数:

    urls.py:
    from
    blog.views import index, archive urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^$', index, name='index'), url(r'^archive/$', archive, name='archive'), # url路由,那么http://127.0.0.1:8000/archive/ 实现了,后面的参数咋办?别急,在views中取出这个请求的参数 ]
    views.py:
    def
    archive(request):
        year = request.GET.get('year', None)
        month = request.GET.get('month', None)   # 取出两个参数 year,month
    
        article_list = Article.objects.filter(date_publish__icontains=year+'-'+month) # 根据参数year,month进行过滤, 记得字段名+__icontains表大小写不敏感的包含匹配
    
        return render(request, 'archive.html', locals())

    至此,我们将所有 http://127.0.0.1:8000/archive/?year=XXX&month=XX 都实现url解析,并筛选出来满足year=XXX,month=XX的文章,下面我们需要在 archive.html 中将这些文章显示出来。

    归档页面archive.html

    在archive.html中加入文章归档显示内容

        <div class="topnews">
          <h2>文章归档</h2>
          {% for article in article_list %}  # 将XXX年XX月的所有文章进行展示
          <div class="blogs">
            <ul>
              <h3><a href="/">{{ article.title }}</a></h3>
              <p>{{ article.desc }}...</p>
              <p class="autor"><span class="lm f_l">{% for tag in article.tag.all %}<a href="/">{{ tag.name }}</a>&nbsp;</span>{% endfor %}<span class="dtime f_l">{{ article.date_publish | date:'Y-m-d' }}</span><span class="viewnum f_r">浏览(<a href="/">{{ article.click_count }}</a></span><span class="pingl f_r">评论(<a href="/">{{ article.comment_set.all.count }}</a></span></p>
            </ul>
          </div>
          {% endfor %}
        </div>
    注:下面也有分页代码

    final:

    注:另一种直接在views.archive中直接进行时间排序处理的方法,没有利用管理器,较为简洁。传送门

  • 相关阅读:
    生成大小字母以及数字混乱的6位验证码
    重写吃货联盟
    集合练习:登录注册功能
    出现并解决Navicat 报错:1130-host ... is not allowed to connect to this MySql server,MySQL
    mysql在linux的安装
    Spring4分别整合mongo2.X和3.0
    oracle数据库使用plsql(64位)时出现的问题
    spring的CXF远程服务
    spring的定时任务或者说自动任务
    jquery节点查询
  • 原文地址:https://www.cnblogs.com/king-lps/p/7338765.html
Copyright © 2020-2023  润新知