【问题标题】:Add method doesnt work when trying to establish m2m relationships using post_save in Django尝试在 Django 中使用 post_save 建立 m2m 关系时,添加方法不起作用
【发布时间】:2016-12-30 17:21:07
【问题描述】:

我的Content 模型与Tag 模型具有many-to-many 关系。当我保存 Content 对象时,我想动态添加关系。我正在按照以下方式执行此操作。

def tag_content(obj):
    for tag in Tag.objects.all():
        print tag
        obj.tags.add(tag)
    obj.is_tagged = True
    obj.save()

class Tag(models.Model):
    name = models.CharField(max_length=255)

class Content(models.Model):
    title = models.CharField(max_length=255)
    is_tagged = models.BooleanField(default=False)
    tags = models.ManyToManyField(Tag, blank=True)

    def save(self, *args, **kwargs):
        super(Content, self).save(*args, **kwargs)

@receiver(post_save, sender = Content)
def update_m2m_relationships_on_save(sender, **kwargs):
    if not kwargs['instance'].is_tagged:
        tag_content(kwargs['instance'])

tag_content 函数运行,但是,m2m 关系未建立。我使用 Django 1.9.8 顺便说一句。这是没有意义的。我错过了什么?此外,如果我在 shell 中执行tag_content(content_instance) 之类的操作,则设置了标签,因此功能正常。我想问题出在接收器上。有什么帮助吗?

编辑

我的问题与 m2m_changed 无关,正如我所说,在 shell 中创建 Content 对象非常有效。因此,问题在于管理面板的设置。

【问题讨论】:

  • 你能确认update_m2m_relationships_on_save 被调用并且它接收到正确的kwargs 吗?这就是我个人调试它的方式。因为你似乎已经验证了所有其他部分......
  • 是的。 print tag 正是这样做的,是的,save 方法正在调用 update_m2m 方法。
  • 尝试在接收器中的if 语句之前打印kwargs['instance']kwargs['instance'].is_tagged,以确保对象和布尔值都是您所期望的
  • 我也试过了,我确实得到了正确的实例。
  • 如果它没有至少保存“is_tagged”字段,这将是一个反馈循环,因为您再次调用保存。它会永远循环。因此,如果它打印出标签(如您所声称的)并且obj 是正确的标签,并且它不会永远循环。这是节省。是否有可能您正在检查过时的数据(例如来自 shell)。几天前我也遇到过这种情况......在运行仔细检查后重新获取该项目。 (值得一试!)

标签: django django-models many-to-many django-orm


【解决方案1】:

好的,我解决了这个问题。基本上,这与 Django 如何在管理面板中处理其表单有关。当尝试从管理员添加内容时,我将标签字段保留为空,认​​为 tag_content 函数会处理它。然而,这正是问题所在,因为从外壳创建内容标记它就好了。换句话说,将管理面板更改为这样解决了我的问题:

from django.contrib import admin
from myapp.models import *
from django import forms

class ContentCreationForm(forms.ModelForm):
    class Meta:
        model = Content
        fields = ('title',)

class ContentChangeForm(forms.ModelForm):
    class Meta:
        model = Content
        fields = ('title', 'is_tagged', 'tags')

class ContentAdmin(admin.ModelAdmin):

    def get_form(self, request, obj=None, **kwargs):
        if obj is None:
            return ContentCreationForm
        else:
            return ContentChangeForm


admin.site.register(Tag)
admin.site.register(Content, ContentAdmin)

尝试创建新内容时,仅显示“标题”字段。这样就解决了问题。

【讨论】:

    猜你喜欢
    • 2016-12-30
    • 2019-03-06
    • 2012-02-29
    • 1970-01-01
    • 2021-10-26
    • 2017-11-21
    • 1970-01-01
    • 2011-02-05
    • 2020-12-04
    相关资源
    最近更新 更多