Skip to main content
 首页 » 编程设计

python之模型字段值未更新 m2m_changed(Django)

2025年04月02日56JustinYoung

我已经搜索了几个小时的答案,但是我找到的每一个答案都不起作用。我自己也试图找到一个错误并没有给我带来任何结果。

我创建了一个 receiver 函数,它应该在每次用户点击像特定图像的按钮。 (这是“Django by Example”一书的一部分)。但是该字段的值始终保持不变,等于默认值 0。即使我尝试手动将值分配给该字段,在 django 的 shell 中,它也不会改变(“更新”部分中的代码示例)。

如果我做错了什么,有人可以看看代码并指出正确的方向吗?

我正在使用 Django 1.9。

# models.py 
class Image(models.Model): 
    ... 
    users_like = models.ManyToManyField(settings.AUTH_USER_MODEL, 
                                    related_name='images_liked', 
                                    blank=True) 
    total_likes = models.PositiveIntegerField(default=5) 
 
    def save(self, *args, **kwargs): 
        if not self.slug: 
            self.slug = slugify(self.title) 
            super(Image, self).save(*args, **kwargs) 
 
# signals.py 
from django.db.models.signals import m2m_changed 
from django.dispatch import receiver 
from .models import Image 
 
@receiver(m2m_changed, sender=Image.users_like.through) 
def users_like_changed(sender, instance, **kwargs): 
    instance.total_likes = instance.users_like.count() 
    instance.save() 
 
# apps.py 
from django.apps import AppConfig 
 
class ImagesConfig(AppConfig): 
    name = 'images' 
    verbose_name = 'Image bookmarks' 
 
    def ready(self): 
        # import signal handlers 
        import images.signals 
 
# __init__.py 
default_app_config = 'images.apps.ImagesConfig' 

更新:

当我从 django shell 运行下面的代码时,这确实改变了 total_likes 值,但它看起来只是暂时的:

from images.models import Image 
for image in Image.objects.all(): 
    print(image.total_likes) 
    image.total_likes = image.users_like.count() 
    print(image.total_likes) 
    image.save() 
    print(image.total_likes) 

上面代码的输出:

0 #initial/default value of 0 
3 #current number of users who like the picture 
3 

因为当我再次运行 for 循环代码时,为了查看结果(甚至检查管理界面中的字段值),我仍然得到初始/默认值 0。

有人能看出字段没有更新的问题吗?

请您参考如下方法:

好的,所以问题出在模型类的自定义 save() 方法上。

我需要像这样调用父类的 save() 方法:

def save(self, *args, **kwargs): 
    if not self.slug: 
        self.slug = slugify(self.title) 
    super(Image, self).save(*args, **kwargs) 

它成功了。