编写Django信号记录模型中的用户活动
这是我在models.py文件中的模型。
class User(AbstractUser):
date_of_birth = models.DateField(blank=True, null=True)
bio = models.TextField(blank=True, null=True)
job = models.CharField(max_length=250, blank=True, null=True)
photo = models.ImageField(upload_to='account_images/',blank=True, null=True)
phone = models.CharField(max_length=11, blank=True, null=True)
followings = models.ManyToManyField('self', through='Contact', related_name='followers', symmetrical=False)
def get_absolute_url(self):
return reverse('social:user_detail', args=[self.username])
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_posts')
description = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
tags = TaggableManager(blank=True)
likes = models.ManyToManyField(User, related_name='liked_post', blank=True)
saved_by = models.ManyToManyField(User, related_name='saved_post', blank=True)
total_likes = models.PositiveIntegerField(default=0)
class Meta:
ordering = ['-created']
indexes = [
models.Index(fields=['-created'])
]
def __str__(self):
return self.author.username
def get_absolute_url(self):
return reverse('social:post_detail', args=[self.id])
class UserActivity(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_activity')
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='post_activity', blank=True, null=True)
action = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.user} {self.action} {self.post.author}' post"
我想写一个信号,也就是说,当用户点赞一篇帖子时,就会创建一个UserActivity模型的对象,并把用户字段设置为点赞的用户。帖子字段应该设置为用户点赞的帖子。而动作字段应该设置为'likes'。
@receiver(post_save, sender=Post.likes.through)
def create_like_activity(sender, instance, **kwargs):
if instance.likes.exists():
UserActivity.objects.create(
user=instance.likes.last(),
post=instance.author,
action='likes'
)
我尝试通过这种方法来实现,但没有成功。我对这些内容还比较陌生,很多概念还处于初学者水平。希望能得到你的指导。
1 个回答
0
你现在关注的信号是错误的。
你应该关注的是 m2m_changed 信号。
要注意,这个信号会被触发多次。
“pre_add” 是在一个或多个对象被添加到关系之前发送的。
“post_add” 是在一个或多个对象被添加到关系之后发送的。
“pre_remove” 是在一个或多个对象从关系中移除之前发送的。
“post_remove” 是在一个或多个对象从关系中移除之后发送的。
“pre_clear” 是在关系被清空之前发送的。
“post_clear” 是在关系被清空之后发送的。
你可以通过检查 action
来了解这个信号何时被触发。
动作:
action 是一个字符串,表示对关系所做的更新类型。
所以,你的代码应该像这样:
@receiver(m2m_changed, sender=Post.likes.through)
def create_like_activity(sender, instance, action, **kwargs):
if instance.likes.exists() and action == "post_add":
UserActivity.objects.create(
user=instance.likes.last(),
post=instance,
action='likes'
)