我正在为客户开发一个传统的Django 1.7系统。我之前的程序员用过滤器查询覆盖了成员模型(基本上是用户模型)“对象”属性,该查询删除了“is_deleted”设置为“True”的任何内容。我列出了以下片段:
会员类摘要:
class Member(AbstractUser):
objects = MemberManager()
all_objects = models.Manager()
MemberManager类代码段:
class MemberManager(BaseUserManager):
def get_queryset(self):
return super(MemberManager, self).get_queryset().filter(is_deleted=False)
现在,当我尝试更新将is_deleted标志设置为“True”的用户时,它将失败。下面是一个示例代码段。请注意我如何使用“all_objects”这是默认的models.Manager(),它返回所有记录。
user = Member.all_objects.get(pk=id) # id of an is_deleted = True record
user.is_deleted = False
user.save()
此代码导致运行此Django查询,但遗憾的是WHERE子句中包含“is_deleted = 0”,这导致它无法找到记录。以下是日志中显示的内容:
UPDATE
Member
[[snip ...]] WHERE(Member
。is_deleted
= 0 ANDMember
。id
= 6)
有没有办法调用不会使用MemberManager.objects get_queryset过滤器的“save()”?
答案 0 :(得分:3)
我认为问题源于首先列出MemberManager
。正如the documentation所说:
请注意,第一个
Manager
Django遇到(按照模型中定义的顺序)具有特殊状态。 Django将类中定义的第一个Manager
解释为“默认”Manager
,Django的几个部分将专门用于该模型Manager
。因此,在选择默认管理器时要小心谨慎,以避免覆盖get_queryset()
导致无法检索您想要使用的对象。
撤销objects
和all_objects
的顺序可以解决问题。
答案 1 :(得分:2)
我尝试了Kevin Christopher Henry的回答,不幸的是,更改默认管理器搞砸了身份验证代码,需要继承" BaseUserManager"类。解决方案是创建一个"取消删除"使用" all_objects"的成员模型类中的函数在用户保存之前取消删除用户的属性。
class Member(AbstractUser):
objects = MemberManager() # default manager
all_objects = models.Manager()
def undelete(self):
if self.is_deleted:
Member.all_objects.filter(id=self.id).update(is_deleted=False)
然后在我的代码中我做了这个:
user = Member.all_objects.get(pk=id)
user.undelete()