Django:尝试访问ManyToMany字段时出错

时间:2020-06-23 18:03:26

标签: django django-models django-orm manytomanyfield

我正在尝试创建一个类似Twitter的应用程序作为练习项目,并遵循此video tutorial。我已经在我的应用中创建了以下模型。

class Profile(models.Model):
    user = models.OneToOneField(to=User, on_delete=models.CASCADE)
    bio = models.CharField(max_length=160, blank=True)
    profile_photo = models.ImageField(blank=True, null=True)
    followers = models.ManyToManyField("self", through="Relationship", related_name="follow_to",
                                       symmetrical=False, blank=True)


class Relationship(models.Model):
    user_followed = models.ForeignKey("User", related_name="followed", on_delete=models.CASCADE)
    followed_by = models.ForeignKey("Profile", related_name="follower", on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now=True)

迁移成功运行。

在进行测试之后,我创建了两个用户(用户1和用户2)及其各自的配置文件,并使用户2跟随用户1。这是该代码-

Relationship.objects.create(user_followed=user1,followed_by=user2.profile)

此关系已成功创建。我尝试以下代码来尝试吸引user1-

的关注者
user1.profile.followers.all()

但是上面的代码给出了以下错误-

Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/mayank/.pyenv/versions/dwitter/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 535, in __get__
return self.related_manager_cls(instance)
File "/Users/mayank/.pyenv/versions/dwitter/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 821, in __init__
self.target_field_name = rel.field.m2m_reverse_field_name()
File "/Users/mayank/.pyenv/versions/dwitter/lib/python3.8/site-packages/django/db/models/fields/related.py", line 1554, in _get_m2m_reverse_attr
return getattr(self, cache_attr)
AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'

我尝试遵循提到的方法here,但是它也给出了相同的错误。我不确定我在哪里犯了错误。如果有人可以纠正我,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

自从ManyToManyField'self'以来,两个ForeignKey都应指向Profile

class Relationship(models.Model):
    followed = models.ForeignKey(
        'Profile',
        related_name='followed',
        on_delete=models.CASCADE
    )
    followed_by = models.ForeignKey(
        'Profile',
        related_name='follower',
        on_delete=models.CASCADE
    )
    timestamp = models.DateTimeField(auto_now=True)

由于现在两个ForeignKey都指向同一个模型,所以 source 字段和 target 字段是什么模棱两可。您可以通过使用through_fields=… parameter [Django-doc]指定这一点来解决此问题:

class Profile(models.Model):
    user = models.OneToOneField(to=User, on_delete=models.CASCADE)
    bio = models.CharField(max_length=160, blank=True)
    profile_photo = models.ImageField(blank=True, null=True)
    followers = models.ManyToManyField(
        'self',
        through='Relationship',
        related_name='follow_to',
        related_fields=('followed', 'followed_by')
        symmetrical=False,
        blank=True
    )

您因此可以使用以下方式创建关注者Relation

Relationship.objects.create(
    followed=user1.profile,
    followed_by=user2.profile
)