Django 将views.py文件中有的数据写成全局变量 这样每个函数都可以用到

在Django中,有时几个页面中要显示的数据一样,或者说一个页面中,点击链接只会刷新其中一部分内容,其他的不变。
这样,我们就可以将相同的、需要渲染在模板中的数据,写成全局的,这样减少代码的重复书写
例如:

在这里插入图片描述
当点击某一个月份文章归档时,只有文章那一块会发生变化,其他都不变化

在这里插入图片描述

然后,我们就需要将其他的做成全局的。
在views.py中

def global_params(request):
    # 该函数中用于保存一些全局变量,每个/多个视图函数都要使用并且代码都没有发生变化的变量。所以可以对这些重复性的代码进行优化,直接设置为全局变量,不用在渲染模版的时候每次都传递这些变量。
    # 查询所有分类信息
    category_list = Category.objects.all()
    # 查询所有广告信息
    ad_list = Ad.objects.all()
    archive_list = Article.objects.archive_date(article_list=Article.objects.all())

    # 评论排行
    # [{'article': 1, 'count': 3},{}]
    article_dict_list = Comment.objects.values('article').annotate(count=Count('article')).order_by('-count')
    # 从查询结果集合QuerySet中,根据article的id,取出这个文章的Model对象。
    result_list = [Article.objects.get(id=article_dict['article']) for article_dict in article_dict_list]
    if len(result_list) > 6:
        result_list = result_list[:6]

    # 浏览排行
    # 三目运算符:a = if b>c? 10:20
    # if条件成立,则取Article.objects.all().order_by('-click_num')[:6]的值;if条件不成立,则取else:Article.objects.all().order_by('-click_num')的值;
    click_list = Article.objects.all().order_by('-click_num')[:6] if len(Article.objects.all()) >= 6 else Article.objects.all().order_by('-click_num')

    # 标签云
    tag_list = Tag.objects.all()

    return {
        'category_list': category_list,
        'ad_list': ad_list,
        'archive_list': archive_list,
        'comment_list': result_list,
        'click_list': click_list,
        'tag_list': tag_list
    }


def process_paginator(request, article_list):
    paginator = Paginator(article_list, 1)
    try:
        page_number = int(request.GET.get('page', '1'))
        page = paginator.page(page_number)
    except (PageNotAnInteger, EmptyPage, InvalidPage):
        page = paginator.page(1)
    return page


def index(request):
    # 所有文章信息
    article_list = Article.objects.all()
    page = process_paginator(request, article_list)
    title = '最新文章'
    # 文章归档:
    # 第一种方法就是定义一个普通的函数archive_article。
    # archive_list = archive_article(article_list)
    # 第二种方式:通过自定义管理器Manager方法实现,通过这种方法,可以实现Article.objects.xxx()的调用方式;
    # 1. 在models.py中自定义一个管理器(一定要继承于内置的Manager类。);
    # 2. 在需要使用的Model类中,注册这个管理器,那么这个Model就可以使用这个管理器方法了;
    # archive_list = Article.objects.archive_date(article_list=article_list)
    return render(request, 'index.html', locals())


def archive(request, year, month):
    # 查询发布日期中含有:2018-10 的数据
    article_list = Article.objects.filter(date_publish__icontains=year+'-'+month)
    page = process_paginator(request, article_list)
    return render(request, 'index.html', locals())

其中的global_params函数里面写的都是下面的函数渲染模板都需要用到的,那么除了将这些数据单独写在一个函数之外,还需要在settings.py中设置:
哪个APP下的哪个文件下的哪个函数是全局的
在这里插入图片描述

这个实现了
其中,在global_params函数中,有一点,将对文章的创建时间的处理封装成了Article类的对象
在这里插入图片描述

能有Article.objects.调用的都是all() get() filter() 是Django封装好的,可直接调用。但是我们也可以自己封装一个,使其能够Article,objects…调用

在models.py中封装:

class ArticleManager(models.Manager):
    def archive_date(self, article_list):
        archive_list = []
        # 需要获取所有的文章model对象。
        for article in article_list:
            # 将每一个文章的发布日期都获取出来,按照'%Y/%m'进行格式化
            pub_date = article.date_publish.strftime('%Y/%m')
            if pub_date not in archive_list:
                # 如果这个时间字符串不在article_list这个列表中,就把这个年月添加进去
                archive_list.append(pub_date)
        return archive_list


class Article(models.Model):
    objects = ArticleManager()
    title = models.CharField(max_length=50, verbose_name='文章标题')
    desc = models.CharField(max_length=50, verbose_name='文章简介')
    content = models.CharField(max_length=255, verbose_name='文章内容')
    click_num = models.IntegerField(verbose_name='点击量', default=0, editable=True)
    comment_num = models.IntegerField(verbose_name='评论量', default=0, editable=True)
    date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')

    tag = models.ManyToManyField(Tag, verbose_name='所属标签')
    category = models.ForeignKey(Category, verbose_name='所属分类', on_delete=models.DO_NOTHING, blank=True, null=True)

注意两点:一、封装的类要继承自models.Manager
二、在要进行Article.objects.调用的Article类中,写上
objects = ArticleManager()
在这里插入图片描述

这样,才可以,在views.py中写:Article.objects.archive_date()
archive_date是封装那个类中的函数
还有,注意传参,一定要一致

猜你喜欢

转载自blog.csdn.net/zhangmengran/article/details/84308720