【发布时间】:2025-12-03 14:15:01
【问题描述】:
所以,我有两个模型集,如下所示:
# 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
第一个 try(#1) 确实从查询集中删除了 user3,但也从数据库中删除了用户本身并打印出以下内容(执行此操作时打印可能不一样,因为这是第三个或我第四次自己尝试这个):
(4, {'accounts.Relationship': 3, 'accounts.User': 1})
第二次try(#2)确实排除了指定的用户,并返回了一个没有用户的新查询集,但是我访问它时原始查询集没有改变,如下所示:
>>> user1.followees.exclude(email='user3@gmail.com')
<QuerySet [<User: user2@gmail.com>]>
>>> user1.followees
<QuerySet [<User: user2@gmail.com>, <User: user3@gmail.com>]>
【问题讨论】:
-
使用models.SET_NULL代替级联docs.djangoproject.com/en/dev/ref/models/fields/…
-
我试试这个看看会发生什么
-
@madzohan 这仍然会删除用户本身。我用
from_user字段中的models.SET_NULL和Relationship类中的to_user字段替换了models.CASCADE
标签: python django django-models django-queryset