So, I have two model sets like the following:
# 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}"
And in the python manage.py shell, I did the following:
>>> 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>]>
Now my main question is related to the user1.followees. I want to delete <User: user3@gmail.com> from the user1.followees queryset without deleting also the user from the database. I've tried the following:
>>> user1.followees[1].delete() # 1
>>> user1.followees.exclude(email='user3@gmail.com') # 2
The first try(#1) does delete the user3 from the queryset, but also deletes the user itself from the database and prints outs the following (The print might not be the same when you do it because this is the third or fourth time I've been trying this on my own):
(4, {'accounts.Relationship': 3, 'accounts.User': 1})
The second try(#2) does exclude the designated user and returns a new queryset without the user, but the original queryset is not altered when I access it, as shown in the following:
>>> user1.followees.exclude(email='user3@gmail.com')
<QuerySet [<User: user2@gmail.com>]>
>>> user1.followees
<QuerySet [<User: user2@gmail.com>, <User: user3@gmail.com>]>