Django - Meta.base_manager_name - 在自定义查询集和管理器中创建相关参数

时间:2017-08-14 05:57:17

标签: django django-queryset django-oscar django-managers

我有一个自定义模型管理器和一个专门为相关obj定义的自定义查询集,这意味着我在模型中定义了Meta.base_manager_name。

我想使用一个all()管理器方法,它在OneToOneFeild上获取相关的obj。

现在我知道这没有意义,因为OneToOneFeild将始终返回一个obj,不需要all()方法。我正在研究django-oscar项目并正在扩展其合作伙伴"模型。它最初有一个字段"用户"使用ManyToManyField,现在更改为OneToOneFeild。

使用关系user.partners.all()在代码中多次调用users字段。我不想扩展/修改所有这些地方(我在这里懒惰吗?),因为我想保持代码尽可能升级友好,所以我想要定义所有()模型管理器,这将是有效的。不确定这是不是一个好主意?

all()方法使用户arg返回用户实例的查询集

class PartnerQuerySet(models.QuerySet):
    def all(self, user):
        return self.filter(user=user)

class PartnerManager(models.Manager):

    def get_queryset(self):
        return PartnerQuerySet(self.model, using=self._db)

    def all(self, user):
        return self.get_queryset().all(users)

class Partner(models.Model):
    objects = PartnerManager()

    class Meta:
        base_manager_name = 'objects'

问题是当它与相关的obj一起使用时它会询问用户arg哪个有意义但是因为我使用它与相关的obj我想使用相关的obj作为arg所以,

user.partner.all() - should use user as arg and fetch the results 

user.partner.all(user) - and I should not have to do the below

2个相关问题: 1)这是否有意义 - 我应该这样做吗? 2)如何在不添加arg用户的情况下实现user.partner.all()

PS:我知道我可以使用中间件来使用get_current_user,但是根据SO上不同问题的一些响应,这个函数不可靠。

1 个答案:

答案 0 :(得分:1)

我不认为你想做的事情会奏效。使用OneToOneField的新情况为您提供了合作伙伴实例。

>>>> user.partner
<Partner xxx>

在使用ManyToManyField的旧情况下,PartnerQuerySet将被返回。

>>>> user.partner
<PartnerQuerySet []>

解决方案是创建自定义OneToOneField,但这很可能违反“简单胜于复杂”规则,最终甚至可能比更改所有现有.all()更多的工作的。