Python 如何使用Django信号从Django中的manytomanyfield获取用户,并使用接收的manytomany用户字段创建另一个对象
我想知道是否有任何方法可以让我们使用信号在一个模型中获得更新的多对多字段,并将其发布到另一个模型Python 如何使用Django信号从Django中的manytomanyfield获取用户,并使用接收的manytomany用户字段创建另一个对象,python,django,django-models,django-views,django-signals,Python,Django,Django Models,Django Views,Django Signals,我想知道是否有任何方法可以让我们使用信号在一个模型中获得更新的多对多字段,并将其发布到另一个模型 class Post(models.Model): name=models.CharField(max_length=24) nc=models.ManyToManyField(settings.AUTH_USER_MODEL) def __str__(self): return self.name # return self.name m2
class Post(models.Model):
name=models.CharField(max_length=24)
nc=models.ManyToManyField(settings.AUTH_USER_MODEL)
def __str__(self):
return self.name
# return self.name
m2m_changed.connect(receiver=like_post,sender=Post.nc.through)
我想在post模型的nc字段中收集更新的记录,并使用信号创建一个使用函数的对象
这是连接到Post模型的信号
def like_post(sender, *args, **kwargs):
# if kwargs['action'] in ('post_update'):
if kwargs['action'] in ('post_add', 'post_remove','post_update'):
print(kwargs['instance'])
instance = kwargs['instance']
print(instance)
notify = Notify.objects.create(
recipient=instance,
creator=Post.objects.get(pk=50),
state='unread',
type=kwargs['action'],
)
else:
print('no instance')
在“收件人和创建者”部分,我想用现有的用户对象更新这些字段。创建者是更新manytomanyfield的人,收件人是创建该帖子的人
notify model:
class Notify(models.Model):
recipient = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='notify_recipient',on_delete=models.CASCADE)
creator = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='notify_sender',on_delete=models.CASCADE)
state = ('read', 'unread', 'unseen')
type = models.CharField(max_length=30, blank=True)
url = models.CharField(max_length=50, blank=True)
每当我运行这个实例时,它只打印post对象名并触发这个错误
ValueError at /admin/posts/post/50/change/
Cannot assign "<Post: ok>": "Notify.recipient" must be a "User" instance.
ValueError位于/admin/posts/post/50/change/
无法分配“”:“Notify.recipient”必须是“用户”实例。
您可以看到,您的Notify类将receipent
定义为身份验证用户模型的外键元素,但您正在信号中创建一个Notify,如下所示:
notify = Notify.objects.create(
recipient=instance,
creator=Post.objects.get(pk=50),
state='unread',
type=kwargs['action'],
)
这里,实例是Post
的实例,而不是User
,而且您也在创建者字段中使用Post
实例。这就是导致错误的原因
要解决此错误,需要在这些字段中传递用户实例。例如,您可以使用以下内容:
notify = Notify.objects.create(
recipient=instance.nc, # find out how to pass the user of the post here
creator=Post.objects.get(pk=50), # replace by an user instance here instead of a post instance
state='unread',
type=kwargs['action'],
)
编辑:
要确保保存用户实例,您需要覆盖ModelAdmin for post model的save_model
方法,如下所示:
class PostAdmin(admin.ModelAdmin):
def save_related(self, request, form, formsets, change):
if not form.cleaned_data['nc']:
form.cleaned_data['nc'] = [request.user]
form.save_m2m()
正如错误所说,收件人是用户的外键。为什么要在那里分配帖子?不,问题不是关于错误,我想知道如何通过signalsCannot assign“”:“Notify.recipient”必须是“user”实例,从帖子模型中的manytomanyfield向该对象发送外键用户(代替收件人),我现在遇到了这个错误,当我打印instance.nc时,终端显示为auth.User.none。这是因为即使保存了post实例,其用户实例也不会立即保存。因此,首先需要确保在执行信号之前保存nc的数据。在使用多对多字段的大多数情况下都会出现此错误。我部分理解了此错误,但有一点我不理解:只有在该post模型的nc已更改的情况下,才会触发信号,对吗?因此,在这种情况下,为什么它没有显示更新的用户,您能否详细说明解决此问题的可能方法?我不明白您关于使用m2m_changed signal的疑问。您声明只有在该post模型的nc发生更改时才会触发该信号是正确的。因此,考虑通过改变任何其他字段而不是nc来激活信号是没有用的。