Django:为model添加自定义的manager进行数据查询

我的网站使用django写的,最近增加了这样一个新需求:后台添加一篇新文章,但并不急于发表,而是现将其隐藏起来,到达特定的时间点后再将其发表。为此,我给原先的article模型添加了一个新的布尔型字段public。这样一来,需要在对article进行查询的源代码中,添加一个过滤器,过滤掉public的值为False的文章。由于在原先的代码中,这样的查询有好多处,逐一进行修改效率太低,而且很容易出错。好在django比较强大,可以直接给model添加自定义的manager进行数据查询,从而轻松地解决我的问题。

原理

manager是django对model进行数据查询的接口。model默认的manager名称是objects,这个名称可以自定义,比如:

from django.db import models

class Article(models.Model):
    #...
    articles = models.Manager()

这段代码中,Article模型的默认的manager名称被改为了articles,可以使用Article.articles.all()获取到数据库中的全部文章;此时,如果使用Article.objects.all()进行查询,会报AttributeError的错误,应为默认的manager名称objects已经被替换掉了。

除了覆盖默认的manager,还可以添加额外的自定义manager,实现更加灵活的数据库查询。比如:

from django.db import models

class PublicArticleManager(models.Manager):
    def get_query_set(self):
        return super(PublicArticleManager, self).get_query_set().filter(public = True)

class Article(models.Model):
    #...
    public =  models.BooleanField('是否发表', default = False)
    
    objects = models.Manager()
    public_articles = PublicArticleManager()

这段代码定义了一个名为PublicArticleManager的Manager类,然后将这个manager添加到了Article模型中,这样Article模型皆可以使用Article.public_articles来查询已经发表的文章了。例如,Article.public_articles.filter(author = "魂亘千秋"),将查询到所有由魂亘千秋写作并发表了的文章。

解决本文开篇的问题

接下来的事情非常简单。在我网站原来的代码中,文章没有已发表和未发表的区别,查询文章使用的是Article.objects。只需要在代码编辑器如notepad++中,通过查询工程下所有的.py文件,将Article.objects批量替换为Article.public_articles即可。

获取更多关于Manager类的信息,可以查看https://docs.djangoproject.com/en/dev/topics/db/managers/

用支付宝钱包扫描此二维码,为本文付款
本文标签:
django

官方公众号:
查看更多有趣的信息,请扫码关注光阴籽官方微信公众号hourseeds。

公众号id:
光阴籽

版权声明:
本文为站长原创,如需转载,请联系作者,并以超链接形式注明出处

本文地址:
http://www.nanerbang.com/article/34/