外键使用django-import-export进行django迁移 [英] Foreign Key in django migration using django-import-export

查看:483
本文介绍了外键使用django-import-export进行django迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 django-import-export 将csv文件加载到我理解的迁移文件是Django 1.7加载初始数据的最佳实践。对于第一个文件,这可以正常工作:

  class Country(models.Model):

ISO2 = models.CharField(max_length = 2,primary_key = True)
name = models.CharField(max_length = 50,unique = True)

和整个迁移文件内容。请注意,ISO2是主键,因此需要添加行import_id_fields = ['ISO2']。从这个问题回答的代码:加载初始数据Django 1.7和数据迁移

 从django.conf导入设置
import tablib
从import_export导入资源
从web.models import国家
import os
import csv

#加载初始数据 - 假设它都在web / fixtures目录

class CountryResource(resources.ModelResource):

class Meta:
model = Country
import_id_fields = ['ISO2']

fixture_dir = os.path.abspath(os.path.join(settings.PROJECT_ROOT,'web / fixtures'))
fixture_filename ='web_country.csv'

def load_fixture(apps, schema_editor)
fixture_file = os.path.join(fixture_dir,fixture_filename)

with open(fixture_file,'r')as content_file:
content = content_ file.read()

resource = CountryResource()

data = tablib.Dataset()
data.csv = content


result = resource.import_data(data,dry_run = False,
raise_errors = True)

def unload_fixture(apps,schema_editor):
严格删除所有条目这个模型...

country = apps.get_model(web,Country)
country.objects.all()。delete()

class Migration(migrations.Migration):

依赖关系= [
('web','0001_initial'),
]

operations = [
migrations.RunPython(load_fixture,reverse_code = unload_fixture),
]

对于与该主键关系关系的下一个文件:

  class CountryFootprint(models.Model):
ISO2 = models.ForeignKey(Country)
footprint = models.DecimalField(max_digits = 18,decimal_p laces = 6)

和迁移文件的一个子集,我尝试链接外键:

  class CountryFootprintResource(resources.ModelResource):

ISO2_id = fields.Field(widget = widgets .ForeignKeyWidget(Country,'ISO2'))

class Meta:
model = CountryFootprint

这给我:

  django.db.models.fields.related.RelatedObjectDoesNotExist:CountryFootprint没有ISO2。 

还试过:

  ISO2_id = fields.Field(column_name ='ISO2_id',attribute ='ISO2',widget = widgets.ForeignKeyWidget(Country,'ISO2'))


文件/Users/phoebebr/Development/gmd/web/migrations/0003_auto_20141220_1931.py,第43行,load_fixture
raise_errors = True)
文件/Users/phoebebr/.virtualenvs/gmd/lib/ python2.7 / site-packages / import_export / resources.py,第359行,import_data
six.reraise(* sys.exc_info())
文件/Users/phoebebr/.virtualenvs/gmd /lib/python2.7/site-packages/import_export/resources.py,第348行,import_data
row_result.object_repr = force_text(instance)
文件/Users/phoebebr/.virtualenvs/gmd /lib/python2.7/site-packages/django/utils/encoding.py,第85行,force_text
s = six.text_type(s)
TypeError:强制转换为Unicode:需要字符串或缓冲区,国家发现

我已经阅读了文档,我确定答案是在那里,但只是不跳出来! p>

解决方案

这两行之一工作:

  ISO2_id = fields.Field(widget = widgets.ForeignKeyWidget(Country,'ISO2'))

  ISO2_id = fields.Field(column_name ='ISO2_id',attribute ='ISO2',widget = widgets.ForeignKeyWidget (国家,ISO2))

只使用:

  fields =('ISO2','footprint')

给出错误

  django.db.models.fields.related.RelatedObjectDoesNotExist:CountryFootprint没有ISO2。 

对Unicode错误的强制是由于我没有从unicode def返回的字符串: p>

  def __unicode __(self):
return self.ISO2

应该是

  def __unicode __(self):
return self.ISO2.name

这么多的编码问题解决了一个好的夜晚睡眠! p>

I'm using django-import-export to load csv files in a migration file which I understand is current best practise for Django 1.7 to load initial data. This worked fine for the first file:

class Country(models.Model):

    ISO2 = models.CharField(max_length=2, primary_key=True)
    name = models.CharField(max_length=50, unique=True)

and the entire migration file contents. note that ISO2 is the primary key so required the addition line import_id_fields = ['ISO2']. Code adapted from answer to this question: Loading initial data with Django 1.7 and data migrations:

from django.conf import settings
import tablib
from import_export import resources
from web.models import Country
import os
import csv

# load initial data - assume it is all in web/fixtures directory

class CountryResource(resources.ModelResource):

    class Meta:
         model = Country
         import_id_fields = ['ISO2']

fixture_dir = os.path.abspath(os.path.join(settings.PROJECT_ROOT, 'web/fixtures'))
fixture_filename = 'web_country.csv'

def load_fixture(apps, schema_editor):
    fixture_file = os.path.join(fixture_dir, fixture_filename)

    with open(fixture_file, 'r') as content_file:
        content = content_file.read()

    resource = CountryResource()

    data = tablib.Dataset()
    data.csv = content


    result = resource.import_data(data,  dry_run=False,
                                 raise_errors=True)

def unload_fixture(apps, schema_editor):
    "Brutally deleting all entries for this model..."

    country = apps.get_model("web", "Country")
    country.objects.all().delete()

class Migration(migrations.Migration):

    dependencies = [
        ('web', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(load_fixture, reverse_code=unload_fixture),
    ]

Now for the next file which has a primary key relationship to that one:

class CountryFootprint(models.Model):
    ISO2 = models.ForeignKey(Country)
    footprint = models.DecimalField(max_digits=18,  decimal_places=6)

and a subset of the migration file, with my attempt to link up the foreign key:

class CountryFootprintResource(resources.ModelResource):

    ISO2_id = fields.Field( widget=widgets.ForeignKeyWidget(Country, 'ISO2'))

    class Meta:
         model = CountryFootprint

This give me:

  django.db.models.fields.related.RelatedObjectDoesNotExist: CountryFootprint has no ISO2.

Also tried:

  ISO2_id = fields.Field(column_name='ISO2_id', attribute='ISO2', widget=widgets.ForeignKeyWidget(Country, 'ISO2'))


  File "/Users/phoebebr/Development/gmd/web/migrations/0003_auto_20141220_1931.py", line 43, in load_fixture
    raise_errors=True)
  File "/Users/phoebebr/.virtualenvs/gmd/lib/python2.7/site-packages/import_export/resources.py", line 359, in import_data
    six.reraise(*sys.exc_info())
  File "/Users/phoebebr/.virtualenvs/gmd/lib/python2.7/site-packages/import_export/resources.py", line 348, in import_data
    row_result.object_repr = force_text(instance)
  File "/Users/phoebebr/.virtualenvs/gmd/lib/python2.7/site-packages/django/utils/encoding.py", line 85, in force_text
    s = six.text_type(s)
TypeError: coercing to Unicode: need string or buffer, Country found

I've read the documentation and I'm sure the answer is there but it's just not jumping out at me!

解决方案

Either of these two lines work:

ISO2_id = fields.Field( widget=widgets.ForeignKeyWidget(Country, 'ISO2'))

or

ISO2_id = fields.Field(column_name='ISO2_id', attribute='ISO2', widget=widgets.ForeignKeyWidget(Country, 'ISO2'))

using just:

fields = ('ISO2', 'footprint')

gives error

django.db.models.fields.related.RelatedObjectDoesNotExist: CountryFootprint has no ISO2.

The coercing to Unicode error was caused by my not having a string returned from the unicode def:

def __unicode__(self):
    return self.ISO2

should have been

def __unicode__(self):
    return self.ISO2.name

so many coding problems solved by a good nights sleep!

这篇关于外键使用django-import-export进行django迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆