2015-06-14 47 views
2

由於未知原因,我無法將Item_rarity表的外鍵實例分配到Detailed_item表中。 Django拋出一個錯誤:django - 無法分配外鍵

無法分配「u'Basic」「:」Detailed_item.rarity「必須是」Item_rarity「實例。

...但在Item_rarity字典「基本」記錄存在 - 我可以從管理面板中選擇它,並手動創建Detailed_item記錄。

我已經定義模式:

class Detailed_item(models.Model): 
    item_id = models.IntegerField(primary_key=True) 
    name = models.CharField(max_length=50) 
    level = models.IntegerField() 
    icon = models.CharField(max_length=150) 
    rarity = models.ForeignKey('Item_rarity') 
    general_type = models.ForeignKey('Item_type') 
    detailed_type = models.ForeignKey('Item_detailed_type') 

class Item_rarity(models.Model): 
    name = models.CharField(max_length=15, primary_key=True) 

class Item_type(models.Model): 
    name = models.CharField(max_length=15, primary_key=True) 

class Item_detailed_type(models.Model): 
    name = models.CharField(max_length=20, primary_key=True) 

在觀點,我嘗試填充它以這種方式(將多個項目):

... 
    items = get_all_items() #get dict of items 
     for element in items: 
      tmp_det_type = '' 
      for key, val in element.iteritems(): 
      #get 'detailed type' from inner dict 
       if key == "type": 
        tmp_det_type = val 

      item = Detailed_item(
       item_id=element['id'], 
       name=element['name'], 
       level=element['level'], 
       icon=element['icon'], 
       rarity=element['rarity'], #error 
       general_type=element['type'], 
       detailed_type=tmp_det_type, 
       ) 

      item.save() 

... 

我甚至嘗試硬編碼「基本」的字符串,但它也不起作用。

*解決* 下面的兩個條目,即Item_typeItem_detailed_type也無效。 正確的代碼:

from app.models import Detailed_item, Item_rarity, Item_type, Item_detailed_type 
... 
    items = get_all_items() #get dict of items 
     for element in items: 
      tmp_det_type = '' 
      for key, val in element.iteritems(): 
      #get 'detailed type' from inner dict 
       if key == "type": 
        tmp_det_type = val 

       #create objects with string values 
       obj_rarity = Item_rarity(name=element['rarity']) 
       obj_item_type = Item_type(name=element['type']) 
       obj_item_detailed_type = Item_detailed_type(name=tmp_det_type) 

       item = Detailed_item(
        item_id=element['id'], 
        name=element['name'], 
        level=element['level'], 
        icon=element['icon'], 
        rarity=obj_rarity, 
        general_type=obj_item_type, 
        detailed_type=obj_item_detailed_type, 
        ) 


      item.save() 

... 
+0

它期待一個對象實例,元素['稀有']的值是什麼? – karthikr

+0

這是一個字符串「Basic」,可以在stdio上打印時沒有問題。 – jligeza

+1

嗯,那麼模型期望一個罕見的實例,其值爲'Basic' – karthikr

回答

5

Item_rarity實例應該同時存儲Detailed_item對象,因爲Item_rarity是Detailed_item對象相關的外鍵進行傳遞。

它可能已經通過了Basic而不是<Basic Object>本身。

在使用它的ORM在django中創建一個對象時,應該爲實例本身提供任何與foreign_key相關的對象,而不是提供對象的id(pk),在從數據庫獲取數據時,您可以使用實例或實例的id(pk)。這裏

class ParentModel(models.Model): 
    model_field = models.CharField(max_length=16) 

class MyModel(models.Model): 
    some_field = models.ForeignKey('ParentModel') 

parent_model = ParentModel.objects.create(model_field='some_data') 

my_model = MyModel.objects.create(some_field=parent_model) 
              ^^^^^^^^^^^^ 

注意,parent_model對象本身,而是隻傳遞了ID

在拿把數據傳回的,

parent_model = ParentModel.objects.get(model_field='some_data') 

my_model = MyModel.objects.get(some_field=parent_model) 

or 

my_model = MyModel.objects.get(some_field=parent_model.id) 

雙方將在工作情況下的數據讀取。

+0

可以用較短的形式編寫它,例如:my_model = parentModel(model_field ='some data') – jligeza

+0

但是兩者之間有什麼區別? –

+0

帶有.objects.create(...)的版本創建一個對象並立即將其插入到數據庫中,而較短的版本需要使用parentModel.save()保存它。在循環內嘗試Item_rarity.objects.create(...)給了我一個完整性錯誤(試圖重複PK)。 – jligeza

0

您沒有提供有關創建相關的對象,如果你改變了kwarg中rarity_name

item = Detailed_item(
      item_id=element['id'], 
      name=element['name'], 
      level=element['level'], 
      icon=element['icon'], 
      rarity_name=element['rarity'], # no error 
      general_type=element['type'], 
      detailed_type=tmp_det_type, 
      ) 

我只與正規id場(自動PK)測試這一點,但它 應該與您的主鍵一起工作就好了。

E.g.

class SimpleModel(Model): 
    value = TextField(blank=True) 

class ComplexModel(Model): 
    simple = ForeingKey(SimpleModel) 
    title = TextField(unique=True) 

ComplexModel.objects.create(title='test', simple_id=1)