因此,我有两个模型集,如下所示:
# User class
class User(AbstractBaseUser, PermissionsMixin):
objects = CustomUserManager()
...
email = models.EmailField(verbose_name='email', max_length=50, null=False, unique=True)
password = models.CharField(verbose_name="password", max_length=200)
name = models.CharField(verbose_name="name", max_length=50)
username = models.CharField(verbose_name="nickname", max_length=50, unique=True)
date_of_birth = models.DateField(verbose_name="birthday", max_length=8)
profile_pic = models.ImageField(verbose_name="profile picture", default="default_profile.png")
USERNAME_FIELD='email'
REQUIRED_FIELDS=['password', 'name', 'username', 'date_of_birth']
followers = models.ManyToManyField(
'self',
symmetrical=False,
through='Relationship',
related_name='followees',
through_fields=('to_user', 'from_user'),
)
@property
def followers(self):
follower_relationship = self.relationship_to_user.filter(relationship_type=Relationship.RELATIONSHIP_TYPE_FOLLOWING)
follower_list = follower_relationship.values_list('from_user', flat=True)
followers = User.objects.filter(pk__in=follower_list)
return followers
@property
def followees(self):
followee_relationship = self.relationship_from_user.filter(relationship_type=Relationship.RELATIONSHIP_TYPE_FOLLOWING)
followee_list = followee_relationship.values_list('to_user', flat=True)
followees = User.objects.filter(pk__in=followee_list)
return followees
def follow(self, to_user):
self.relationship_from_user.create(
to_user = to_user,
relationship_type='f'
)
def __str__(self):
return self.username
# Relationships class
class Relationship(models.Model):
RELATIONSHIP_TYPE_FOLLOWING = 'f'
RELATIONSHIP_TYPE_BLOCKED = 'b'
CHOICE_TYPE = (
(RELATIONSHIP_TYPE_FOLLOWING, '팔로잉'),
(RELATIONSHIP_TYPE_BLOCKED, '차단'),
)
from_user = models.ForeignKey(
User,
related_name='relationship_from_user',
on_delete=models.CASCADE,
)
to_user = models.ForeignKey(
User,
related_name='relationship_to_user',
on_delete=models.CASCADE,
)
relationship_type=models.CharField(max_length=1, choices=CHOICE_TYPE)
def __str__(self):
return f"{self.from_user} follows {self.to_user}, type={self.relationship_type}"
在python manage.py shell
中,我做了以下操作:
>>> user1 = User.objects.get(id=1) # user1@gmail.com
>>> user2 = User.objects.get(id=2) # user2@gmail.com
>>> user3 = User.objects.get(id=3) # user3@gmail.com
>>> user1.follow(user2)
>>> user1.follow(user3)
>>> user1.followees
<QuerySet [<User: user2@gmail.com>, <User: user3@gmail.com>]>
现在我的主要问题是关于user1.followees
。我想从user1.followees
查询集中删除<User: user3@gmail.com>
,而不从数据库中删除用户。我试过以下几种:
>>> user1.followees[1].delete() # 1
>>> user1.followees.exclude(email='user3@gmail.com') # 2
第一次尝试(#1(确实从查询集中删除了user3,但也从数据库中删除了用户本身,并打印出以下内容(打印时可能不一样,因为这是我自己第三次或第四次尝试(:
(4, {'accounts.Relationship': 3, 'accounts.User': 1})
第二次尝试(#2(确实排除了指定的用户,并返回了一个没有用户的新查询集,但当我访问它时,原始查询集没有改变,如下所示:
>>> user1.followees.exclude(email='user3@gmail.com')
<QuerySet [<User: user2@gmail.com>]>
>>> user1.followees
<QuerySet [<User: user2@gmail.com>, <User: user3@gmail.com>]>
Manytomany有添加和删除关系的特定方法。
user1.followees.remove(user3)
此外,除非您在follow()
方法中需要自定义逻辑,否则您可能只需要使用user1.followees.add(user3)
。
user1.followees.clear()
可以移除所有的跟随者。
https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/
我似乎是从我正在做的事情访问用户本身:
>>> user1.followees[0] --> This accesses the user who's in the followees[0], not the relatioship itself
因此,当我尝试删除查询集时,我正在访问用户本身,所以我实际上是在删除查询集和用户本身。因此,我的解决方案是访问关系,而不是用户。我做了以下事情:
>>> Relationship.objects.all()
<QuerySet [<Relationship: user1@gmail.com follows user2@gmail.com, type=f>, <Relationship: user1@gmail.com follows user3@gmail.com type=f>]>
>>> Relationship.objects.all()[0]
<QuerySet [<Relationship: user1@gmail.com follows user3@gmail.com, type=f>]>
>>> Relationship.objects.all()[0].delete()
(1, {'accounts.Relationship': 1})
并检查关系模型和user1关系:
>>> Relationship.objects.all()
<QuerySet [<Relationship: user1@gmail.com follows user3@gmail.com type=f>]>
>>> user1.followees
>>> <QuerySet [<User: user2@gmail.com>]>
这就是答案!
**这个方法是可能的,但@user1464664给出的答案要好得多,所以我建议研究一下这个