Могу ли я добавить менеджера в отношения «многие-многие»?

У меня есть две модели, которые каким-то образом связаны со «сквозной» таблицей?

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()

or

bike.bikeusers.commonMethod()

Каков наилучший способ добиться этого?


person Joelbitar    schedule 02.10.2010    source источник


Ответы (2)


Когда у вас есть модель 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
person OmerGertel    schedule 02.10.2010
comment
Спасибо, это сработало как шарм! Однако, если я вызываю менеджера из экземпляра Bike bike.bikeuser_set.commonMethod(), как мне получить доступ к велосипеду из общего метода? (это должен быть новый вопрос?) - person Joelbitar; 02.10.2010
comment
Я думаю, вам придется добавить его как параметр функции: def commonMethod(self,bike) и использовать его следующим образом: bike.bikeuser_set.commonMethod(bike) - person OmerGertel; 02.10.2010
comment
Вот что я делал, я думал, что есть лучший способ, в любом случае большое спасибо! - person Joelbitar; 03.10.2010

use_for_related_fields устарело в django 2.0. Использование для связанных полей возможно через управляющий базой.

Старый:

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'

источник примера

Помните о ограничения для метода get_queryset().

person MartinP    schedule 24.05.2020