Django - 将用作管理器的自定义查询集与抽象类继承相结合

时间:2017-01-17 22:07:17

标签: django

基本上,我必须在我的项目中实现目前在实施方面相互冲突的两个目标。

目标是:

  1. 为模型实例启用可链接筛选(my_model.objects.custom_filter1()。custom_filter2()等)
  2. 对于那些包含is_deleted字段的表,我想排除标记为已删除的记录,这样我就不必显式过滤已删除的记录(使用my_model.objects.all()代替{{1} })
  3. 目前我有以下代码:

    my_model.objects.filter(is_deleted = false)

    然而,我的第一个目标似乎变得不可行。在使用抽象类来实现第二个目标之前,我有以下代码 解决第二个目标:

    class MixinManager(models.Manager): 
        def get_queryset(self):
            try:
                return self.model.MixinQuerySet(self.model).filter(is_deleted=False)
            except FieldError:
                return self.model.MixinQuerySet(self.model)
    
    class BaseMixin(models.Model):
        objects = MixinManager()
    
    class MixinQuerySet(QuerySet):
        pass
        class Meta:
           abstract = True
    
    class DeleteMixin(BaseMixin):
        is_deleted = models.BooleanField(default=False)
    
        class Meta:
            abstract = True
    
    class Sms(DeleteMixin):
        # core fielrds
        # objects = SmsQuerySet.as_manager()
        class Meta:
            managed = False
            db_table = 'sms'
    

    这种语法解决了我的第一个目标。

    问题:

    问题是我无法将这两个结构合并为一个逻辑,因此我可以写:

    class SmsQuerySet(models.query.QuerySet):
        def filter_1(self, user):
            return self.filter(...)
        def filter_2(self, user):
            return self.filter(...)
    
        def filter_3(self, user):
            return self.filter(...)
    
    class Sms(models.Model):
       # core fields
       objects = SmsQuerySet.as_manager()
    

    以便从sms.objects.filter_1().filter_2().filter_3() 中排除已删除的记录。 如果我取消注释第一个代码段中的sms.objects行,那么# objects = SmsQuerySet.as_manager() objects字段将被忽略,我将在最终查询集中删除已删除的记录。另一方面,如果我对该行进行评论,那么我的自定义查询集将无法访问。

    我希望我能够简明扼要地描述我想要做的事情。将非常感谢任何解决方案的暗示!

1 个答案:

答案 0 :(得分:0)

应该有效

from django.db import models

class SmsQuerySet(models.query.QuerySet):
    def filter_1(self, user):
        return self.filter(...)
    def filter_2(self, user):
        return self.filter(...)

    def filter_3(self, user):
        return self.filter(...)


class MixinManager(models.Manager): 
    def get_queryset(self):
        try:
            return SmsQuerySet(self.model).filter(is_deleted=False)
        except FieldError:
            return SmsQuerySet(self.model)


class Sms(models.Model):
   # core fields
   objects = MixinManager()