Pau*_*ite 28 python django django-queryset
在Django中,如果我有一个模型类,例如
from django.db import models
class Transaction(models.Model):
...
Run Code Online (Sandbox Code Playgroud)
然后,如果我想向模型添加方法,存储例如相当复杂的过滤器,我可以添加自定义模型管理器,例如
class TransactionManager(models.Manager):
def reasonably_complex_filter(self):
return self.get_query_set().filter(...)
class Transaction(models.Model):
objects = TransactionManager()
Run Code Online (Sandbox Code Playgroud)
然后我可以这样做:
>>> Transaction.objects.reasonably_complex_filter()
Run Code Online (Sandbox Code Playgroud)
有什么办法可以添加一个可以链接到模型查询集末尾的自定义方法吗?
即添加自定义方法,以便我可以这样做:
>>> Transaction.objects.filter(...).reasonably_complex_filter()
Run Code Online (Sandbox Code Playgroud)
Bur*_*lid 40
从django 1.7开始,添加了使用查询集作为管理器的能力:
class PersonQuerySet(models.QuerySet):
def authors(self):
return self.filter(role='A')
def editors(self):
return self.filter(role='E')
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
role = models.CharField(max_length=1, choices=(('A', _('Author')),
('E', _('Editor'))))
people = PersonQuerySet.as_manager()
Run Code Online (Sandbox Code Playgroud)
结果如下:
Person.people.authors(last_name='Dahl')
Run Code Online (Sandbox Code Playgroud)
此外,还添加了添加自定义查找的功能.
Dan*_*mov 15
这是一个完整的解决方案,已知在Django 1.3中工作,由Zach Smith和Ben提供.
class Entry(models.Model):
objects = EntryManager() # don't forget this
is_public = models.BooleanField()
owner = models.ForeignKey(User)
class EntryManager(models.Manager):
'''Use this class to define methods just on Entry.objects.'''
def get_query_set(self):
return EntryQuerySet(self.model)
def __getattr__(self, name, *args):
if name.startswith("_"):
raise AttributeError
return getattr(self.get_query_set(), name, *args)
def get_stats(self):
'''A sample custom Manager method.'''
return { 'public_count': self.get_query_set().public().count() }
class EntryQuerySet(models.query.QuerySet):
'''Use this class to define methods on queryset itself.'''
def public(self):
return self.filter(is_public=True)
def by(self, owner):
return self.filter(owner=owner)
stats = Entry.objects.get_stats()
my_entries = Entry.objects.by(request.user).public()
Run Code Online (Sandbox Code Playgroud)
注意:该get_query_set()方法现在在Django 1.6中已弃用 ; get_queryset()在这种情况下应该使用.
您需要添加QuerySet最终最终的方法.因此,您需要创建和使用一个QuerySet子类,该子类具有您在任何需要此功能的地方定义的方法.
我找到了这个教程,它解释了如何做到这一点以及你可能想要的原因:
http://adam.gomaa.us/blog/2009/feb/16/subclassing-django-querysets/index.html