Django信号跟随/取消关注

问题描述 投票:0回答:1

我有一个看起来像这样的信号:

@receiver([post_save, post_delete], sender=Following)
def increment_follow_count(instance, created=False, **kwargs):
    if created:
        instance.follower.following_count += 1
        instance.target.follower_count += 1
    else:
        instance.follower.following_count -= 1
        instance.target.follower_count -= 1

[当一个用户关注另一个用户时,它可以正常工作。但是,当同一用户取消关注该用户时,只有该用户关注的对象(目标)的追随者计数递减,但该用户的追随者计数不会递减。为什么会发生这种现象,我该如何解决?

型号:

class Following(models.Model):
    target = models.ForeignKey('User', related_name='followers', on_delete=models.CASCADE, null=True)
    follower = models.ForeignKey('User', related_name='targets', on_delete=models.CASCADE, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return '{} is followed by {}'.format(self.target, self.follower)

要关注/取消关注用户的代码

def follow_unfollow(follower, target):
    # Query to see if the following exists or not
    following = target.followers.filter(follower=follower)

    if following.exists():
        following.delete()
    else:
        target.followers.create(follower=follower)

    target.save()
    follower.save()
python django django-models django-signals
1个回答
0
投票

[increment_follow_count]信号包含增量逻辑,但没有保存逻辑,是否完成保存是另一种follow_unfollow方法?


首先,increment优于beatomic,以确保不会丢失任何更改。

使用F() expressions可以实现原子增量。

from django.db.models import F

@receiver([post_save, post_delete], sender=Following)
def increment_follow_count(instance, created=False, **kwargs):
    if created:
        User.objects.filter(
            pk=instance.follower_id
        ).update(
            following_count=F('following_count') + 1
        )
        User.objects.filter(
            pk=instance.target_id
        ).update(
            following_count=F('following_count') + 1
        )
    else:
        User.objects.filter(
            pk=instance.follower_id
        ).update(
            following_count=F('following_count') - 1
        )
        User.objects.filter(
            pk=instance.target_id
        ).update(
            following_count=F('following_count') - 1
        )

这里的增量不仅是原子的,而且更改会立即保存在数据库中使用相同的方法。

此外,我建议删除target.save()中的follower.save()follow_unfollow-因为它是数据库中具有内存值的overwrites实例,并且不应该这样,至少对于following_count,因为其增量逻辑已输入信号。如果在follow_unfollow方法中对字段进行了一些更改,而不是followng_count,则应使用save()调用update_fields list以仅更新更改的字段。


常规update_fields获取当前的内存中实例字段值,即+= 1,增量(count=5)和后期,当调用save时,它将被保存为更新count=6。并且在此期间,数据库中的值可能已经更改了很多次(无论更新如何将其设置为6),尤其是在加载/同时操作的情况下。

随着原子增量逻辑从python移至数据库-并将在进行事务处理时增加实际值。

© www.soinside.com 2019 - 2024. All rights reserved.