Джанго, во многих отношениях внутри класса self, как я могу ссылаться друг на друга с точки зрения ORM?

class User(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    gender = models.IntegerField()
    email = models.CharField(max_length=100)
    password = models.CharField(max_length=255)
    following = models.ManyToManyField("self", related_name='followers')
    objects = UserManager()
    def __repr__(self):
        return "User: {0}".format(self.name)

В моей модели User пользователи могут подписываться и следовать друг за другом.

Я могу найти, за кем следит пользователь:

user1 = User.objects.get(id=1)
following = user1.following.all()

Однако я не могу понять, как узнать, за кем следует пользователь.

Я старался:

user1.followers.all()

так как это related_name в следующем поле в моей модели.

Кто-нибудь может научить меня, как это сделать?

Большое спасибо.


person Jung    schedule 23.08.2017    source источник
comment
Возможный дубликат Как реализовать последователей/отслеживание в Django   -  person Jmills    schedule 12.10.2018


Ответы (1)


Вы должны передать symmetrical атрибут должен быть False.

Из документов:

Когда Django обрабатывает эту модель, он идентифицирует, что у нее есть ManyToManyField, и в результате он не добавляет атрибут followers к классу User. Вместо этого предполагается, что ManyToManyField симметричен, то есть если я твой follower, то ты мой follower.

Если вам не нужна симметрия в отношениях "многие ко многим" с self, задайте для symmetrical значение False. Это заставит Django добавить дескриптор обратного отношения, что позволит отношениям ManyToManyField быть несимметричными.

В твоем случае:

class User(models.Model):
    # ...
    following = models.ManyToManyField('self', related_name='followers', symmetrical=False)
    # ...

Затем в вашем views.py вы можете получить доступ к обоим:

following = user.following.all()
followers = user.followers.all()

С этого момента отношения с self несимметричны.

person wencakisa    schedule 23.08.2017