简体   繁体   English

绕过自定义模型管理器以获取ManyToMany对象

[英]Bypassing custom Model Manager to get ManyToMany objects

I'm working on a maintenance project which has a model say Business with a custom Model Manager. 我正在一个维护项目中,该项目的模型为“ Business”和一个自定义Model Manager。 This custom Model Manager adds some extra filter to all the queries executing on Business models. 这个自定义的模型管理器为在业务模型上执行的所有查询添加了一些额外的过滤器。 This Business model has a ManyToMany field to self named Trainers. 此业务模型有一个自称为Trainers的ManyToMany字段。 So far so good, the issue comes in when I try to fetch all the Trainers associated with the Business without applying those filters. 到目前为止,当我尝试在不应用这些过滤器的情况下尝试获取与业务相关的所有培训师时,就会出现问题。

The Business model is as given below: 业务模型如下:

class Business(Basetable):
    #status P=publish    H=inactive    D=draft    N=new
    name = models.CharField(max_length=120)
    slug = models.SlugField(max_length=150)
    logo=models.OneToOneField("BusinessLogo",null=True,on_delete=models.SET_NULL)
    categories = models.ManyToManyField("BusinessCategory",related_name='allcategories',null=True)
    price_type = models.CharField(max_length=2,
                                      choices=PRICE_CHOICES,
                                      default=YEARLY, null=True, blank=True)
    achievements = models.TextField(null=True, blank=True)
    years_of_experience = models.FloatField(null=True, blank=True)

    trainers = models.ManyToManyField("self",related_name='btrainers',null=True, blank=True, symmetrical=False)
    expense=models.IntegerField(null=True,blank=True)
    objects= CityManager()

    def get_trainers(self):
      return self.trainers.all()

get_trainers is the function which returns all the Trainers associated with the Business, however I want the results to bypass the CityManager and use the default Manager. get_trainers是返回与业务相关联的所有培训师的函数,但是我希望结果绕过CityManager并使用默认的Manager。

Any pointers will be appreciated. 任何指针将不胜感激。

Update: 更新:

using use_for_related_fields = False does not work. 使用use_for_related_fields = False无效。 I found a related bug here. 我在这里找到了一个相关的错误 Is there a work around? 有没有解决的办法? I know that overriding the default objects is not a good practice, however this is what I have received. 我知道重写默认objects不是一个好习惯,但这是我收到的。

In general, it's better to avoid filtering results in the default Manager : 通常,最好避免在默认的Manager 过滤结果

It's a good idea to be careful in your choice of default manager in order to avoid a situation where overriding get_queryset() results in an inability to retrieve objects you'd like to work with. 最好谨慎选择默认管理器,以避免覆盖get_queryset()导致无法检索要使用的对象的情况。

But if you can't change the default Manager for backwards-compatibility reasons, you can still explicitly create a plain Manager and get your results using that. 但是,如果由于向后兼容的原因而不能更改默认Manager ,则仍然可以显式创建一个普通Manager并使用该结果获取结果。

class Business(Basetable):
    ...
    objects = CityManager()  # Still the first listed, and default
    plain_objects = models.Manager()

Now that you have a plain Manager , use it to explicitly access the desired objects: 现在您有了一个普通的Manager ,使用它可以显式访问所需的对象:

def get_trainers(self):
    return Business.plain_objects.filter(btrainers__id=self.id)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM