2013-05-15 40 views
4

我在Django中定義了一個模型。我想爲其QuerySet對象定義一些自定義方法。 (即我想定義自定義方式來過濾該對象的實例,但只以該模型特有的方式)。Django:爲特定模型的「QuerySet」對象提供自定義過濾方法

現在,我可以在Manager上定義那些對象,但這些方法只能在Manager上訪問而不是任何單一的QuerySet,這是對該模型進行任何類型的過濾的結果。

所以:我如何給我的模型自定義過濾方法的QuerySet對象?

+0

你在找自定義管理員嗎? https://docs.djangoproject.com/zh/dev/topics/db/managers/#custom-managers – PepperoniPizza

回答

5

如果您需要篩選器鏈接擴展Queryset。從我目前的項目

一個例子:

from django.db import models 
from django.db.models.query import QuerySet 

class MemberQuerySet(QuerySet): 

    def in_group(self, group): 
     return self.filter(group_set__pk=group.pk) 

    def not_in_group(self, group): 
     return self.exclude(groups_set__pk=group.pk) 

class MemberManager(models.Manager): 

    def get_queryset(self): 
     return MemberQuerySet(self.model, using=self._db) 

    def in_group(self, group): 
     return self.get_queryset().in_group(group) 

    def not_in_group(self, group): 
     return self.get_queryset().not_in_group(group) 

class Member(models.Model): 

    # ... 

    objects = MemberManager() 

有了這個,你可以這樣做:

Member.objects.in_group(one_group).not_in_group(another_group) 

如果您不需要過濾器鏈接與自定義方法的管理者就足夠了。 這在docs中涵蓋的很好。

This snippet似乎更快QuerySet插件不錯,但它是舊的(4年)和我從來沒有嘗試過

1

復活這個提供了一個更好,更乾淨的方式來做到這一點。

至少從Django的1.8(在任何earlier..it可以被引入這個API時,或可能無法正常工作,不知道未測試),還有一個好得多的辦法做到這一點...

from django.db import models 
from django.db.models.query import QuerySet 

class MemberQuerySet(QuerySet): 
    def in_group(self, group): 
     return self.filter(group_set__pk=group.pk) 

    def not_in_group(self, group): 
     return self.exclude(group_set__pk=group.pk) 

    # etc.. 

class Member(models.Model): 
    # fields.. 

    objects = MemberQuerySet.as_manager() 

然後你可以這樣做..

Member.objects.in_group(group1).not_in_group(group2) 
相關問題