2017-04-19 48 views
1

嘗試將項目列表批量添加到多對多字段時遇到了一些麻煩,儘管嘗試了各種各樣的東西並不知道如何處理這個。我看過Django文檔,似乎找不到我在找什麼。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的殼循環外同樣的事情似乎是工作,並保存條目,但它不會在函數內部。

>>> 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

所以我把什麼羅伯特建議,並在外殼的作品就像在上面的管理界面只是不使用時。我的代碼中的打印語句顯示正在更新的數組項目,但它不會持續。我周圍閱讀,這似乎是一個問題與保存前的管理員表單清除項目。

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

一旦有了subject對象(如你在你的編輯),你可以用

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

加入他們「item_subjects」屬性管理相關項目的方式。通過關係是通過「添加」方法創建的。

一旦你做到了這一點,你可以做這樣的事情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()方法(我假設這個代碼存在)。它調用的第二種方法是「save_related」,它首先清除ManyToMany關係,然後根據提交的表單數據保存它們。在你的情況下,沒有有效的表單數據,因爲你在保存時創建了對象。

如果您將此代碼的相關部分放入管理員的save_related()方法中,則更改應該保留。

如果您將<應用> /models.py和<應用> /admin.py文件發佈,我可以更具體地說明它應該發展到哪裏。從另一個SO問題

參考: Issue with ManyToMany Relationships not updating inmediatly after save

+0

感謝您的幫助,它仍然沒有工作因爲某種原因。儘管在django shell中工作得幾乎相同。例如'>>> K [0] .item_subjects.all() >>> d,B = Subject.objects.get_or_create(名詞= 「貓」) >>> d <主題:貓> > >> k [0] .item_subjects.add(d) >>> k [0] .item_subjects.all() ]>'還有什麼我必須在這裏做的。 –

+0

很高興它在shell中工作。注意編輯以顯示您在shell之外使用的新代碼(仍然無法運行的代碼?),現在您已經添加了.add()方法了? –

+0

kk謝謝,我已經更新了一遍。 –

相關問題