【发布时间】:2021-04-18 23:30:06
【问题描述】:
我正在尝试为我的模型实现该行为,以便在您删除对象时它不会物理删除,而只是添加一些属性以表明它已被删除。
所以我创建了自定义查询集、管理器和 mixin 来应用到每个创建的模型:
class StateQuerySet(models.query.QuerySet):
def delete(self):
self.update(active=False)
class StateManager(models.Manager):
def get_queryset(self):
return StateQuerySet(self.model, using=self._db).filter(active=True)
class ModelMixin(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
active = models.BooleanField(default=True)
objects = StateManager()
def delete(self, *args, **kwargs):
self.active = False
self.save()
class Meta:
abstract = True
还有模特:
class Organizer(ModelMixin, models.Model):
name = models.CharField(max_length=256)
class EventData(ModelMixin, models.Model):
caption = models.CharField(max_length=512)
description = models.TextField(blank=True, default='')
organizer = models.ForeignKey(Organizer, on_delete=models.CASCADE)
所以,这个想法是当我做任何事情时:
Organizer.objects.all() / Organizer.objects.filter(name__startswith='<some_start_prefix>')
我只会收到 active=True(即“未删除”)的 Organizer 对象。 一切看起来都不错,但是当我有相关对象时,就会出现问题。 例如,如果我这样做:
EventData.objects.filter(organizer__name__startswith='<some_start_prefix>')
它将返回所有 EventData 对象,即使是“已删除”。 但如果我这样做:
EventData.objects.filter(organizer__name__startswith='<some_start_prefix>', organizer__active=True)
所有工作都按预期进行,仅返回“活动”记录。所以我不想使用:
organizer__active=True
对于视图中的每个查询。
我已阅读文档,但仍然不明白如何使用自定义 Manager 和 QuerySet 创建它。您能否提供帮助或指导如何执行此操作?我错过了什么?
总结一下:当我这样做时:
EventData.objects.filter(organizer__name__startswith='<some_start_prefix>')
我想收到 Organizer.active 设置为 True 的所有 EventData 对象,但无需每次在客户端代码中编写额外的 Organizer__active=True。是否可以在Manager或QuerySet中进行?
【问题讨论】:
-
您能否澄清一下,在您的过滤器中包含
organizer__active=True会为您提供您想要的结果,但您不想在查询中使用它? -
@markwalker_ 不,我想要,我只是想要它在某个通用的地方。我不想将它添加到我每次在视图中使用它的所有地方(例如)。据我所知,可以通过自定义管理器和查询集来做到这一点,但我不明白如何。正如您在 get_queryset 中看到的一样: StateQuerySet(self.model, using=self._db).filter(active=True) 因此,对于在模型上完成的每个 get/filter,它只会返回“活动”。但它不适用于相关对象。
标签: python django django-models django-queryset django-managers