【问题标题】:Django override model get() method won't work on foreign keysDjango覆盖模型get()方法不适用于外键
【发布时间】:2021-05-22 23:05:16
【问题描述】:

我有一个自定义模型定义如下,get() 方法覆盖

class CustomQuerySetManager(models.QuerySet):
    def get(self, *args, **kwargs):
        print('Using custom manager')
        # some other logics here...
        return super(CustomQuerySetManager, self).get(*args, **kwargs)


class CustomModel(models.Model):
    objects = CustomQuerySetManager.as_manager()

    class Meta:
        abstract = True

然后我有两个模型定义为

class Company(CustomModel):
    name = models.CharField(max_length=40)

class People(CustomModel):
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=20)

如果我像People.objects.get(pk=1) 一样直接使用get(),那么它可以工作,“使用自定义管理器”会打印出来,但是如果我尝试获取外键信息,django 仍然使用默认管理器中的get() 方法,例如,没有打印任何内容,并且定义的其余逻辑将不会被执行

someone = People.objects.get(id=1)  # prints Using custom manager, custom logic executed
company_name = someone.company.name  # nothing gets printed, custom logic does not execute

即使外键模型也使用我的自定义模型类,模型中的外键字段是否使用不同的管理器?有没有办法让我的自定义 get() 方法适用于所有字段?

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    正如 django 文档所说

    默认情况下,Django 使用 Model._base_manager 管理器的实例 访问相关对象(即choice.question)时的类,而不是 _default_manager 在相关对象上

    查看更多here

    所以你必须告诉 django model 使用哪个管理器作为基础管理器,像这样:

    class CustomModel(models.Model):
        objects = CustomQuerySetManager.as_manager()
    
        class Meta:
            #django will use your custom "objects" manager as base_manager
            #or you may have different managers for base and default managers
            #if you define two managers with different names
            base_manager_name = 'objects' 
            abstract = True
    

    但是,请注意不要过滤掉来自基本经理的任何结果。 Django 文档说:

    此管理器用于访问与某些对象相关的对象 其他型号。在这些情况下,Django 必须能够看到所有 它正在获取的模型的对象,因此任何 引用的可以检索。

    因此,不要为此类经理覆盖get_queryset()。 查看更多here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-23
      • 2016-05-13
      • 2021-11-21
      • 1970-01-01
      相关资源
      最近更新 更多