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

时间:2016-08-06 17:32:43

标签: python django django-models django-signals

我一直在寻找一个小时的答案,但是我找到的每个答案都不起作用。同时试图找到我自己的错误并没有给我带来任何结果。

我创建了一个receiver function,每次用户点击特定图片的“赞”按钮时,都会更新模型的total_likes属性(基于users_like属性的数量) 。 (这是“示例书”中的Django的一部分)。但是字段的值始终保持不变并且等于默认值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。

有人可以看到该字段未更新的原因吗?

1 个答案:

答案 0 :(得分:1)

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

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

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

它使它成功。