python - 如何在 Django 中从查询集中删除而不删除原始模型本身

标签 python django django-models django-queryset

所以,我有两个模型集,如下所示:

# 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)    # <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="196c6a7c6b28597e74787075377a7674" rel="noreferrer noopener nofollow">[email protected]</a> 
>>> user2 = User.objects.get(id=2)    # <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a4d1d7c1d696e4c3c9c5cdc88ac7cbc9" rel="noreferrer noopener nofollow">[email protected]</a>
>>> user3 = User.objects.get(id=3)    # <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b8cdcbddca8bf8dfd5d9d1d496dbd7d5" rel="noreferrer noopener nofollow">[email protected]</a>
>>> user1.follow(user2)
>>> user1.follow(user3)
>>> user1.followees
<QuerySet [<User: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="295c5a4c5b1b694e44484045074a4644" rel="noreferrer noopener nofollow">[email protected]</a>>, <User: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="483d3b2d3a7b082f25292124662b2725" rel="noreferrer noopener nofollow">[email protected]</a>>]>

现在我的主要问题与user1.followees有关。 。我要删除<User: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ef9a9c8a9ddcaf88828e8683c18c8082" rel="noreferrer noopener nofollow">[email protected]</a>>来自user1.followees查询集,而不从数据库中删除用户。我尝试过以下方法:

>>> user1.followees[1].delete()                         # 1
>>> user1.followees.exclude(email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="add8dec8df9eedcac0ccc4c183cec2c0" rel="noreferrer noopener nofollow">[email protected]</a>')    # 2

第一次尝试(#1)确实从查询集中删除了 user3,但也从数据库中删除了用户本身并打印出以下内容(当您执行此操作时,打印可能会有所不同,因为这是第三次或我第四次自己尝试这个):

(4, {'accounts.Relationship': 3, 'accounts.User': 1})

第二次尝试(#2)确实排除了指定用户并返回一个没有用户的新查询集,但是当我访问它时原始查询集没有改变,如下所示:

>>> user1.followees.exclude(email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="36434553440576515b575f5a1855595b" rel="noreferrer noopener nofollow">[email protected]</a>')
<QuerySet [<User: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="81f4f2e4f3b3c1e6ece0e8edafe2eeec" rel="noreferrer noopener nofollow">[email protected]</a>>]>
>>> user1.followees
<QuerySet [<User: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f98c8a9c8bcbb99e94989095d79a9694" rel="noreferrer noopener nofollow">[email protected]</a>>, <User: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="651016001756250208040c094b060a08" rel="noreferrer noopener nofollow">[email protected]</a>>]>

最佳答案

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/

关于python - 如何在 Django 中从查询集中删除而不删除原始模型本身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65247618/

相关文章:

python - 系统还原后无法从 Windows 7 卸载 Python 3.4.2

python - MultipleChoiceField 未在 Django Admin 中显示存储的值

python - Django 测试显示导入错误,但项目通过运行服务器成功运行

python - 将分类值转换为 Pandas 中的列

python - 所有可能的 (1,2....x) 字母组合

python - 如何使用 Numba 优化随机 Runge-Kutta?

django - 在 django 中自动完成并允许在未找到时创建用户

python - 异常值 :attempt to write a readonly database Centos 8 Apache webserver Python 3. 6

python - 经历多个多对多关系的Django ORM方式

python - 永久指定模型的使用