尝试将项目列表批量添加到多对多字段时遇到了一些麻烦,虽然尝试了各种各样的事情并不知道如何处理这个问题。我查看了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_save
和post_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)
但这会产生一个递归循环或者不会触发。
答案 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