【问题标题】:Can I add a manager to a manytomany relationship?我可以在多对多关系中添加经理吗?
【发布时间】:2010-10-02 13:09:39
【问题描述】:

我有两个模型以某种方式与“直通”表存在多对多关系?

class Bike(models.Model):
   nickname = models.CharField(max_length=40)
   users    = models.ManyToManyField(User, through='bike.BikeUser')

BikeUser 类

class BikeUser(models.Model):
   bike     = models.ForeignKey(Bike)
   user     = models.ForeignKey(User)
   comment  = models.CharField(max_length=140)

我想为 Bike 类添加与用户合作的功能,是否有最佳实践方式来做到这一点。我想避免向 Bike 类添加太多方法,而是让某种管理器来处理

类似:

bike.bikeusers_set.commonMethod()

bike.bikeusers.commonMethod()

最好的方法是什么?

【问题讨论】:

    标签: django django-models manytomanyfield


    【解决方案1】:

    拥有 BikeUser 模型后,您可以向模型添加自定义管理器。

    类似:

    class BikeUserManager(models.Manager):
        def commonMethod():
            pass
    
    class BikeUser(models.Model):
       bike     = models.ForeignKey(Bike)
       user     = models.ForeignKey(User)
       comment  = models.CharField(max_length=140)
       objects  = BikeUserManager()
    

    但您只能在 BikeUser 模型中使用它:

    BikeUser.objects.commonMethod()
    

    您想要的是将此经理用作相关经理: http://docs.djangoproject.com/en/dev/topics/db/managers/#controlling-automatic-manager-types

    use_for_related_fields=True 添加到管理器类。

    class MyManager(models.Manager):
        use_for_related_fields = True
    

    【讨论】:

    • 谢谢你,这就像一个魅力! Howerver,如果我从实例化的 Bike bike.bikeuser_set.commonMethod() 调用经理我如何从 commonMethod 中访问“bike”? (这应该是一个新问题吗?)
    • 我认为您必须将其添加为函数参数:def commonMethod(self,bike) 并像这样使用它:bike.bikeuser_set.commonMethod(bike)
    • 这就是我一直在做的,我认为有更好的方法,还是非常感谢你!
    【解决方案2】:

    use_for_related_fields 已从 django 2.0 中弃用。可通过base manager 使用相关字段。

    旧:

    class CustomManager(models.Model):
        use_for_related_fields = True
    
    class Model(models.Model):
        custom_manager = CustomManager()
    

    新:

    class Model(models.Model):
        custom_manager = CustomManager()
    
        class Meta:
            base_manager_name = 'custom_manager'
    

    source of example

    记住restrictions 用于get_queryset() 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多