英文:
Why in Django many-to-many relation shows wrong data in the admin panel
问题
我正在尝试实现多对多关系,以支持用户模型中的以下功能:
1)用户的关注者(关注该用户的人)
2)用户的关注对象(用户关注的人)
为了实现这一点,我在同一个模型上使用了双重关系,因为关注者/关注对象都是同一个用户模型。
基本上它可以工作,但是我在Django管理面板中遇到了奇怪的行为。当我将某个用户添加到另一个用户的关注对象列表中(在shell中一切正常),Django管理面板显示该用户在关注者列表中,但实际上他应该在关注对象列表中。我无法理解为什么会发生这种情况。
非常感谢任何帮助!
我的models.py文件如下:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
followers = models.ManyToManyField('self', blank=True, related_name='user_followers', symmetrical=False)
following = models.ManyToManyField('self', blank=True, related_name='user_following', symmetrical=False)
pass
假设管理员想要关注Neo。Neo应该有一个关注者-管理员。管理员应该在他的关注对象列表中有Neo。
以下是在shell中执行的命令和结果:
admin = User.objects.filter(username='admin')[0]
neo = User.objects.filter(username='neo_anderson')[0]
# 检查是否为空
neo.user_following.all()
# <QuerySet []>
neo.user_followers.all()
# <QuerySet []>
# --- 管理员想要关注Neo ---
# 将管理员添加到Neo的关注者列表中
neo.user_followers.add(admin)
neo.save()
# 将Neo添加到管理员的关注对象列表中
admin.user_following.add(neo)
admin.save()
# 检查管理员是否关注Neo
admin.user_following.contains(neo)
# TRUE
# 检查Neo是否有关注者管理员
neo.user_followers.contains(admin)
# TRUE
但是在管理面板中,我看到对于用户Admin,用户Neo在关注者部分,但实际上应该在关注对象部分,因为管理员想要关注Neo,而不是相反。
英文:
I'm trying to implement the many-to-many relation to support in the user model these features:
- user followers (persons who follows the user)
- user following (persons the user follows)
To achieve that I'm using double relation on the same model because followers/following are the same User models.
Basically it works hoverwer I'm facing a weird behavior in the Django admin panel. When I add some user to other user to the following list (in the shell everything ok), the Django admin panel shows that user in the followers list but he should be in the following list. I can't understand why it happens.
<br><br>Many thanks for any help!
<br /><br>
My models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
followers = models.ManyToManyField('self',blank=True,related_name='user_followers',symmetrical=False)
following = models.ManyToManyField('self',blank=True,related_name='user_following',symmetrical=False)
pass
Supppose Admin wants to follow Neo. Neo should have follower - Admin. Admin - should have Neo in his following list.
Shell commands and result:
admin = User.objects.filter(username='admin')[0]
neo = User.objects.filter(username='neo_anderson')[0]
// check that everything is empty
neo.user_following.all()
<QuerySet []>
neo.user_followers.all()
<QuerySet []>
// --- admin wants to follow neo ---
// add the admin to the neo followers
neo.user_followers.add(admin)
neo.save()
// add the neo to the admin following
admin.user_following.add(neo)
admin.save()
// check if admin follows Neo
admin.user_following.contains(neo)
TRUE
// check if neo has the follower admin
neo.user_followers.contains(admin)
TRUE
But in the admin panel I see that for the user Admin the user Neo is in the followers section but it should be following because Admin wants to follow Neo. Not vice versa
答案1
得分: 1
首先使用以下代码:
admin = User.objects.get(username='admin'),避免使用需要索引的列表(更简洁)。
其次,我不确定"related_name"属性的工作原理和行为如何,但你是否尝试过切换/使用相反的方式?我会假设关注者会关注"我",也就是说他们具有"following"属性,而不是"followers"属性!?
也许我错了,但可以尝试以下代码:
followers = models.ManyToManyField('self', blank=True, related_name='user_following', symmetrical=False)
following = models.ManyToManyField('self', blank=True, related_name='user_followers', symmetrical=False)
(记得将这些更改迁移到数据库中)
我很好奇那时的行为是什么,请告诉我。
英文:
First of all use:
admin = User.objects.get(username='admin') to avoid having a list, that you need to index... (cleaner)
Second:
I am not sure how the "related_name" property is working exactly and how it would behave, but have you tried switching / using the opposite? I would assume followers would follow "me", meaning they have the following attribute, instead of the followers attribute!?
Maybe I am wrong, but try:
followers = models.ManyToManyField('self',blank=True,related_name='user_following',symmetrical=False)
following = models.ManyToManyField('self',blank=True,related_name='user_followers',symmetrical=False)
(remember to migrate those changes to the database)
I would be curious what the behavior is then, please let me know
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论