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

Model field value does not get updated m2m_changed(Django)

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

我创建了一个 receiver function,它应该在用户每次单击特定图像的“赞”按钮时更新模型的 total_likes 属性(基于 users_like 属性的数量)。 (这是“Django by Example”一书的一部分)。但是该字段的值始终保持不变,等于默认值 0。即使我尝试手动将值分配给该字段,在 django 的 shell 中,它也不会改变([=36 中的代码示例=] 节)。

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

我正在使用 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 循环代码时,为了查看结果(甚至检查管理界面中的字段值)我仍然得到 initial/default 值 0.

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

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

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

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

它成功了。