【问题标题】:Django - call Model save() without using "objects" Manager get_querysetDjango - 在不使用“对象”管理器 get_queryset 的情况下调用模型 save()
【发布时间】:2014-11-25 18:05:44
【问题描述】:

我正在为客户开发旧版 Django 1.7 系统。我之前的程序员使用过滤器查询覆盖了成员模型(基本上是用户模型)的“对象”属性,该过滤器查询删除了“is_deleted”设置为“True”的任何内容。我在下面列出了 sn-ps:

成员类sn-p:

class Member(AbstractUser):
    objects = MemberManager()
    all_objects = models.Manager()

MemberManager 类 sn-p:

class MemberManager(BaseUserManager):
    def get_queryset(self):
        return super(MemberManager, self).get_queryset().filter(is_deleted=False)

现在,当我尝试更新将 is_deleted 标志设置为“True”的用户时,它会失败。下面是一个示例代码 sn-p。请注意我如何使用“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”,这导致它找不到记录。以下是日志中显示的内容:

更新Member [[snip...]] 在哪里(Member.is_deleted = 0 和 Member.id = 6)

有什么方法可以调用不使用 MemberManager.objects get_queryset 过滤器的“save()”吗?

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    我认为问题源于将MemberManager 列在首位。正如the documentation 所说:

    请注意,Django 遇到的第一个 Manager(按照它们在模型中定义的顺序)具有特殊状态。 Django 将类中定义的第一个Manager 解释为“默认”Manager,Django 的几个部分将专门为该模型使用该Manager。因此,最好谨慎选择默认管理器,以避免覆盖 get_queryset() 导致无法检索您想要使用的对象的情况。

    颠倒objectsall_objects 的顺序应该可以解决问题。

    【讨论】:

      【解决方案2】:

      我尝试了凯文克里斯托弗亨利的回答,不幸的是,更改默认管理器搞砸了身份验证代码,该代码需要从“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()
      

      【讨论】:

        猜你喜欢
        • 2021-12-15
        • 2012-06-06
        • 2013-05-04
        • 1970-01-01
        • 2012-07-26
        • 1970-01-01
        • 2013-05-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多