Django将从一个字段的文本生成的列表添加到多个到多个字段

时间:2017-04-19 18:40:33

标签: python django django-models django-orm

尝试将项目列表批量添加到多对多字段时遇到了一些麻烦,虽然尝试了各种各样的事情并不知道如何处理这个问题。我查看了Django文档,似乎无法找到我正在寻找的东西。

以下是我的模型的代码:

class Subject(models.Model):
    noun = models.CharField(max_length=30, null=True, blank=True)

class Knowledge(models.Model):
    item_text = models.TextField()
    item_subjects =  models.ManyToManyField(Subject, null=True, blank=True)

def add_subjects(sender, instance, *args, **kwargs):

    if instance.item_info:
         item_subjects = classifier.predict_subjects(instance.item_info)

         if item_subjects:
             ....

post_save.connect(add_subjects, sender=Knowledge)

该列表由classifer.predict_subjects函数生成。 我尝试使用m2m_changed连接器以及pre_savepost_save连接。我甚至不确定多对多领域是否是正确的选择,做一个外键关系会更好。 取代'...'我尝试了这个但是它没有创建关系,只保存最后一个。

for sub in item_subjects:
    subject = Subject(id=instance.id, noun=sub)
    subject.save()

我也试过

instance.item_subjects = item_subjects

并且还有更多我无法记住的事情,我真的不认为我是正确的球场。有什么建议吗?

修改

好的,所以我已经添加了所有列表项,但仍然没有设法将这些项链接到多对多的字段。

        for sub in item_subjects:
            subject = Subject.objects.get_or_create(noun=sub)

编辑2:

因此,在Django shell中循环外几乎完全相同的东西似乎正在工作并保存条目,但它不在函数内部。

>>> k[0].item_subjects.all()
<QuerySet []>
>>> d, b = Subject.objects.get_or_create(noun="cats")
<Subject: cats>
>>> k[0].item_subjects.add(d)
>>> k[0].item_subjects.all()
<QuerySet [<Subject: cats>]>

编辑3

所以我接受了Robert建议的内容,它就像上面一样在shell中运行,而不是在管理界面中使用它时。我的代码中的print语句显示了正在更新的数组项,但它只是坚持不变。我在四处阅读,这似乎与保存前管理表单清除项目有关。

def sub_related_changed(sender, instance, *args, **kwargs):

    print instance.item_subjects.all()

    if instance.item_info:
        item_subjects = classifier.predict_subjects(instance.item_info)

        if item_subjects:
            for sub in item_subjects:
                subject, created = Subject.objects.get_or_create(noun=sub)
                instance.item_subjects.add(subject)

        print instance.item_subjects.all()


post_save.connect(sub_related_changed, sender=Knowledge)

我已尝试将此功能用作m2m_changed信号,如下所示:

m2m_changed.connect(model_saved, sender=Knowledge.item_subjects.through)

但这会产生一个递归循环或者不会触发。

1 个答案:

答案 0 :(得分:0)

获得subject个对象(就像编辑中一样),可以添加

for sub in item_subjects:
    subject, created = Subject.objects.get_or_create(noun=sub)
    instance.item_subjects.add(subject)

&#34; item_subjects&#34;属性是管理相关项的一种方式。直通关系是通过&#34;添加&#34;方法

完成此操作后,您可以执行instance.item_subjects.filter(noun='foo')instance.item_subjects.all().delete()等操作

文档参考:https://docs.djangoproject.com/en/1.11/topics/db/examples/many_to_many/

修改 啊,我没有意识到这是在Django Admin中发生的。我认为你是对的,这就是问题所在。保存后,管理员调用两个方法:第一个是model_save(),它调用模型的save()方法(我假设这个代码存在)。它调用的第二种方法是&#34; save_related&#34;首先清除ManyToMany关系,然后根据提交的表单数据保存它们。在您的情况下,没有有效的表单数据,因为您在保存时创建了目标。

如果将此代码的相关部分放入admin的save_related()方法中,则更改应保持不变。

如果您发布&lt;&lt;&lt; p&gt;我可以更具体地说明它应该去哪里app&gt; /models.py和你的&lt; app&gt; /admin.py文件。

来自另一个SO问题的参考: Issue with ManyToMany Relationships not updating inmediatly after save