【问题标题】:Django Custom Manager for Reverse Foreignkey Lookup (Related Manager)用于反向外键查找的 Django 自定义管理器(相关管理器)
【发布时间】:2020-04-02 13:53:08
【问题描述】:

我正在使用自定义模型管理器进行软删除,并希望进行反向外键查找(相关管理器)。

经理:

class SoftDeletionQuerySet(QuerySet):
    def delete(self):
        return super(SoftDeletionQuerySet, self).update(deleted_at=timezone.now())

    def hard_delete(self):
        return super(SoftDeletionQuerySet, self).delete()

    def alive(self):
        return self.filter(deleted_at=None)

    def dead(self):
        return self.exclude(deleted_at=None)


class SoftDeletionManager(models.Manager):
    use_for_related_fields = True

    def __init__(self, *args, **kwargs):
        self.status = kwargs.pop("status", "all")
        super(SoftDeletionManager, self).__init__(*args, **kwargs)

    def get_queryset(self):
        if self.status == "alive":
            return SoftDeletionQuerySet(self.model).filter(deleted_at=None)
        elif self.status == "dead":
            return SoftDeletionQuerySet(self.model).exclude(deleted_at=None)
        else:
            return SoftDeletionQuerySet(self.model)

    def hard_delete(self):
        return self.get_queryset().hard_delete()



class SoftDeletionModel(models.Model):
    deleted_at = models.DateTimeField(blank=True, null=True)

    objects = SoftDeletionManager(status="alive")
    dead_objects = SoftDeletionManager(status="dead")
    all_objects = SoftDeletionManager()

    class Meta:
        abstract = True

    def delete(self):
        self.deleted_at = timezone.now()
        self.save()

    def hard_delete(self):
        super(SoftDeletionModel, self).delete()

用于模型:

class Sowi(SoftDeletionModel):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

现在,对于给定的user,我想获得他的user.sowi_set,但只有那些“活着”的 SoWi。 “正常”user.sowi_set 还返回已死的元素,即具有deleted_at 值!= 无。 如何只获取活动对象?

提前致谢!

【问题讨论】:

    标签: python django django-models django-views


    【解决方案1】:

    user.sowi_set.all()被调用时,你的管理器会被django自动初始化,参数为空。为了解决这个问题,我在django初始化manager时寻找了传递参数的方法。然后,我找到了this question

    您必须像这样更改代码。

    def manager_factory(status=None):
        class SoftDeletionManager(models.Manager):
            deletion_status = status
            use_for_related_fields = True
    
            def get_queryset(self):
                if self.deletion_status == "alive":
                    return SoftDeletionQuerySet(self.model).filter(deleted_at=None)
                elif self.deletion_status == "dead":
                    return SoftDeletionQuerySet(self.model).exclude(deleted_at=None)
                else:
                    return SoftDeletionQuerySet(self.model)
    
            def hard_delete(self):
                return self.get_queryset().hard_delete()
        return SoftDeletionManager()
    
    
    class SoftDeletionModel(models.Model):
        deleted_at = models.DateTimeField(blank=True, null=True)
    
        objects = manager_factory("alive")
        dead_objects = manager_factory("dead")
        all_objects = manager_factory()
    
        class Meta:
            abstract = True
    
        def delete(self):
            self.deleted_at = timezone.now()
            self.save()
    
        def hard_delete(self):
            super(SoftDeletionModel, self).delete()
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-01
      • 1970-01-01
      • 2011-11-28
      • 2021-06-07
      • 2020-09-01
      相关资源
      最近更新 更多