VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • 建立一个更高级别的查询 API:正确使用Django ORM 的方式(5)

Todo.objects.incomplete().high_priority() # yay!

除上面那些输入部分、且非常不DRY,每次你新增一个文件到QuerySet,或是更改现有的方法标记,你必须记住在你的Manager中做相同的更改,否则它可能不会正常工作。这是配置的问题。

方法3b: django-model-utils

 

Python 是一种动态语言。 我们就一定能避免所有模块?一个名叫Django-model-utils的第三方应用带来的一点小忙,就会有点不受控制了。先运行 pip install django-model-utils ,然后……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from model_utils.managersimport PassThroughManager
 
class TodoQuerySet(models.query.QuerySet):
    def incomplete(self):
        return self.filter(is_done=False)
 
    def high_priority(self):
        return self.filter(priority=1)
 
class Todo(models.Model):
    content= models.CharField(max_length=100)
    # other fields go here..
 
    objects= PassThroughManager.for_queryset_class(TodoQuerySet)()

 

这要好多了。我们只是象之前一样 简单地定义了自定义QuerySet子类,然后通过django-model-utils提供的PassThroughManager类附加这些QuerySet到我们的model中。

 

PassThroughManager 是由__getattr__ 实现的,它能阻止访问到django定义的“不存在的方法”,并且自动代理它们到QuerySet。这里需要小心一点,检查确认我们没有在一些特性中没有无限递归(这是我为什么推荐使用django-model-utils所提供的用不断尝试测试的方法,而不是自己手工重复写)。

做这些有什么帮助?

记得上面早些定义的视图代码么?

1
2
3
4
5
6
7
8
9
10
11
12
13
def dashboard(request):
 
    todos= Todo.objects.filter(
        owner=request.user
    ).filter(
        is_done=False
    ).filter(
        priority=1
    )
 
    return render(request,'todos/list.html', {
        'todos': todos,
    })

相关教程