从用户访问反向 manytomany 字段到 onetoone 相关模型时出错
Error accesing reverse manytomany field from user to onetoone related model
我在处理与用户模型具有一对一关系的模型类时遇到问题,这是冲突的部分:
class UserInteraction(models.Model):
user = models.OneToOneField(User, related_name="interactions", on_delete=models.CASCADE)
users_follows = models.ManyToManyField('self', through='UserFollow', blank=True, symmetrical=False, related_name='user_follows')
users_likes = models.ManyToManyField('self', through='UserLike', blank=True, symmetrical=False, related_name='user_likes')
当我尝试通过 user.interactions.user_follows
或 user.interactions.user_likes
获取 follows/likes 时,出现以下错误:
In [18]: u = User.objects.get(id=1)
In [19]: u.interactions.users_likes.all()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [19], in <module>
----> 1 u.interactions.users_likes.all()
File ~\...\django\db\models\fields\related_descriptors.py:536, in ReverseManyToOneDescriptor.__get__(self, instance, cls)
533 if instance is None:
534 return self
--> 536 return self.related_manager_cls(instance)
File ~\...\django\db\models\fields\related_descriptors.py:826, in create_forward_many_to_many_manager.<locals>.ManyRelatedManager.__init__(self, instance)
824 self.prefetch_cache_name = rel.field.name
825 self.source_field_name = rel.field.m2m_field_name()
--> 826 self.target_field_name = rel.field.m2m_reverse_field_name()
827 self.symmetrical = rel.symmetrical
828 else:
File ~\...\django\db\models\fields\related.py:1598, in ManyToManyField._get_m2m_reverse_attr(self, related, attr)
1596 setattr(self, cache_attr, getattr(f, attr))
1597 break
-> 1598 return getattr(self, cache_attr)
AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'
这是 fk 中使用的跟随者和类似模型:
class UserFollow(TimeStampBase):
follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower')
followed = models.ForeignKey(User, on_delete=models.CASCADE, related_name='followed')
class Meta:
constraints = [
models.UniqueConstraint(
name="%(app_label)s_%(class)s_unique_relationships",
fields=["followed", "follower"],
),
models.CheckConstraint(
name="%(app_label)s_%(class)s_prevent_self_follow",
check=~models.Q(follower=models.F("followed")),
),
]
def __str__(self):
return f'{self.follower} follows {self.followed}'
class UserLike(TimeStampBase):
liker = models.ForeignKey(User, on_delete=models.CASCADE, related_name='liker')
liked = models.ForeignKey(User, on_delete=models.CASCADE, related_name='liked')
class Meta:
constraints = [
models.UniqueConstraint(
name="%(app_label)s_%(class)s_unique_relationships",
fields=["liked", "liker"],
),
models.CheckConstraint(
name="%(app_label)s_%(class)s_prevent_self_follow",
check=~models.Q(liker=models.F("liked")),
),
]
def __str__(self):
return f'{self.liker} likes {self.liked}'
在管理员中一切正常,我做错了什么?
通过模型中的 ForeignKey 字段需要引用包含 ManyToManyField 的模型而不是 OneToOneField 中的模型 - UserInteraction
而不是 User
class UserFollow(TimeStampBase):
follower = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='follower')
followed = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='followed')
...
class UserLike(TimeStampBase):
liker = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='liker')
liked = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='liked')
...
我在处理与用户模型具有一对一关系的模型类时遇到问题,这是冲突的部分:
class UserInteraction(models.Model):
user = models.OneToOneField(User, related_name="interactions", on_delete=models.CASCADE)
users_follows = models.ManyToManyField('self', through='UserFollow', blank=True, symmetrical=False, related_name='user_follows')
users_likes = models.ManyToManyField('self', through='UserLike', blank=True, symmetrical=False, related_name='user_likes')
当我尝试通过 user.interactions.user_follows
或 user.interactions.user_likes
获取 follows/likes 时,出现以下错误:
In [18]: u = User.objects.get(id=1)
In [19]: u.interactions.users_likes.all()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [19], in <module>
----> 1 u.interactions.users_likes.all()
File ~\...\django\db\models\fields\related_descriptors.py:536, in ReverseManyToOneDescriptor.__get__(self, instance, cls)
533 if instance is None:
534 return self
--> 536 return self.related_manager_cls(instance)
File ~\...\django\db\models\fields\related_descriptors.py:826, in create_forward_many_to_many_manager.<locals>.ManyRelatedManager.__init__(self, instance)
824 self.prefetch_cache_name = rel.field.name
825 self.source_field_name = rel.field.m2m_field_name()
--> 826 self.target_field_name = rel.field.m2m_reverse_field_name()
827 self.symmetrical = rel.symmetrical
828 else:
File ~\...\django\db\models\fields\related.py:1598, in ManyToManyField._get_m2m_reverse_attr(self, related, attr)
1596 setattr(self, cache_attr, getattr(f, attr))
1597 break
-> 1598 return getattr(self, cache_attr)
AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'
这是 fk 中使用的跟随者和类似模型:
class UserFollow(TimeStampBase):
follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower')
followed = models.ForeignKey(User, on_delete=models.CASCADE, related_name='followed')
class Meta:
constraints = [
models.UniqueConstraint(
name="%(app_label)s_%(class)s_unique_relationships",
fields=["followed", "follower"],
),
models.CheckConstraint(
name="%(app_label)s_%(class)s_prevent_self_follow",
check=~models.Q(follower=models.F("followed")),
),
]
def __str__(self):
return f'{self.follower} follows {self.followed}'
class UserLike(TimeStampBase):
liker = models.ForeignKey(User, on_delete=models.CASCADE, related_name='liker')
liked = models.ForeignKey(User, on_delete=models.CASCADE, related_name='liked')
class Meta:
constraints = [
models.UniqueConstraint(
name="%(app_label)s_%(class)s_unique_relationships",
fields=["liked", "liker"],
),
models.CheckConstraint(
name="%(app_label)s_%(class)s_prevent_self_follow",
check=~models.Q(liker=models.F("liked")),
),
]
def __str__(self):
return f'{self.liker} likes {self.liked}'
在管理员中一切正常,我做错了什么?
通过模型中的 ForeignKey 字段需要引用包含 ManyToManyField 的模型而不是 OneToOneField 中的模型 - UserInteraction
而不是 User
class UserFollow(TimeStampBase):
follower = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='follower')
followed = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='followed')
...
class UserLike(TimeStampBase):
liker = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='liker')
liked = models.ForeignKey(UserInteraction, on_delete=models.CASCADE, related_name='liked')
...