2015-02-24 132 views
2

我不明白django-import-export模塊如何處理ForeignKeys。 下面是一個簡單爲例: models.py在django-import-export中處理foreignKeys的導入

class TFamilies(models.Model): 
    id_fam = models.AutoField(primary_key=True, unique=True) 
    name_fam = models.CharField(max_length=1024, blank=True,verbose_name='Famille') 


class TGenus(models.Model): 
    id_genus = models.AutoField(primary_key=True, unique=True) 
    name_genus = models.CharField(max_length=1024,verbose_name='nom de genre') 
    id_fam = models.ForeignKey(TFamilies, null=True, db_column='id_fam', blank=True, verbose_name='Famille') 

我想,讓人們加入屬與家人有關!一個只有name_genus和name_fam的CSV/XLS ...(和id留空)。

家庭已經存在於數據庫的大部分時間,Django的中庸之道必須找到正確的身份證號碼......

admin.py

class TGenusResource(resources.ModelResource): 

    name_fam = fields.Field(widget=widgets.ForeignKeyWidget(TFamilies, 'name_fam')) 

    class Meta: 
     model = TGenus 
     import_id_fields = ['id_genus'] 


class TGenusAdmin(ImportExportActionModelAdmin): 
    form = TGenusAdminForm 
    resource_class = TGenusResource 
    pass 

這種配置導致錯誤在導入接口:

Line number: 1 - 'NoneType' object has no attribute 'name_fam' 
Traceback (most recent call last): 
File "/....../lib/python2.7/site-packages/import_export/resources.py", line 348, in import_data 
row_result.object_repr = force_text(instance) 
File "......./lib/python2.7/site-packages/django/utils/encoding.py", line 85, in force_text 
s = six.text_type(s) 
AttributeError: 'NoneType' object has no attribute 'name_fam' 

我不明白... 我也試着回答有:django-import-export resource definition for foreignkey field? 和有點像有:Foreign Key in django migration using django-import-export

我必須用before_import找到自己的比賽嗎?

回答

1

我發現你必須找到自己的匹配!在tablib數據集中改變數值是不可能的,所以你必須讓條目進行更改並將它們放回新行,然後刪除舊數據。

我的excel模板包含填充姓名的家庭的列id_genus(空),name_genusid_fam

對於任何人誰落在這裏我發表我的方式:

def before_import(self, dataset, dry_run): 
     """ 
     Make standard corrections to the dataset before displaying to user 
     """ 

     i = 0 
     last = dataset.height - 1 

     # for all lines, search for id of family given and add a new line at the bottom with it then delete the first one 
     while i <= last: 
      # Check if the Genus exist in DB 
      if (TGenus.objects.filter(name_genus=dataset.get_col(2)[0].capitalize())): 
       id_genus = TGenus.objects.filter(name_genus=dataset.get_col(2)[0].capitalize())[0].id_genus 
      else : 
       id_genus = '' 
      # Check if the family exists in DB 
      try: 
       TFamilies.objects.get(name_fam=dataset.get_col(2)[0].capitalize()) 
      except TFamilies.DoesNotExist: 
       raise Exception("Family not in DB !")     
      except TFamilies.MultipleObjectsReturned: 
       pass 

      # use of "filter" instead of "get" to prevent duplicate values, select the first one in all cases 
      dataset.rpush((id_genus, 
       dataset.get_col(1)[0], 
       TFamilies.objects.filter(name_fam=dataset.get_col(2)[0].capitalize())[0].id_fam)) 
      dataset.lpop() 
      i = i + 1 

我的Django管理可以通過非SYS管理員使用,這樣,他們可以和複製屬或不在DB家庭... 如果有人有更好的處理錯誤的想法,我想閱讀它! 此外,我想保留在預覽中的家庭的名稱,不僅她的身份證...如果你知道如何,我已經發布了另一個問題:Is-it possible to customize the template of preview in django import-export?