【问题标题】:Django signal to follow/unfollowDjango 发出跟随/取消关注的信号
【发布时间】:2020-04-15 22:28:53
【问题描述】:

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

@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()

【问题讨论】:

  • 请分享模型定义,我怀疑接收器正在监听错误的对象更改并且没有正确跟踪相关模型更新
  • @GiorgiJambazishvili 嗨,我刚刚用模型更新了问题
  • 当用户取消关注其他用户时,您是否正在删除该对象?如果是,那么您需要使用 post_delete 信号。您能否添加更多代码来显示未关注用户的流程?
  • @NalinDobhal 另外,我正在使用 post_delete 看看信号
  • 可能你只需要在模型更改计数中添加一个方法,你可以在其中捕获每个更改,然后在保存后调用它

标签: python django django-models django-signals


【解决方案1】:

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


首先,增量最好原子,以确保不会丢失任何更改。

使用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
        )

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

另外,我建议删除follow_unfollow 中的target.save()follower.save() - 因为它用内存中的值覆盖 数据库中的实例,而这不应该是这样,至少对于following_count,因为它的增量逻辑处于信号状态。如果在follow_unfollow 方法中对字段进行了一些更改,而不是followng_count - 那么应该使用update_fields list 调用save() 以仅更新更改的字段。


正则+= 1取当前内存实例字段值,即count=5,递增(count=6),稍后,当调用save时,它被保存为更新@ 987654337@。在此期间,数据库中的值可能已经更改了很多次(无论如何更新都会将其设置为 6),尤其是在加载/同时操作时。

使用原子增量逻辑从 python 移动到数据库 - 并将在进行事务时增加实际值。

【讨论】:

  • 我收到此错误:in increment_follow_count following_count=F('following_count') - 1 TypeError: 'int' object is not callable
  • 在查询集中 (User.objects.filter().update(f_c=F('f_c')-1))?似乎直接在实例上调用/修改字段,而不是在查询集中。
  • 啊,这是一个导入问题,没有错误,但由于某种原因,这似乎没有更新 following_count
  • target.save(); follower.save() 是否已从 follow_unfollow 中删除?
  • 在关注/取消关注操作时,target.save() / follower.save() 在其他地方吗?用户单击关注/取消关注按钮时的数据库 SQL 查询日志会很有帮助。
猜你喜欢
  • 2020-03-14
  • 1970-01-01
  • 2014-09-27
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多