2014-12-20 2 views
2

Я использую django-import-export для загрузки файлов csv в файл миграции, который, как я понимаю, является лучшей практикой для Django 1.7 для загрузки исходных данных. Это сработало отлично для первого файла:Иностранный ключ в миграции django с использованием django-import-export

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']. Код адаптирован от ответа на этот вопрос: 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), 
    ] 

Теперь следующий файл, который имеет первичный ключ отношение к этому один:

class CountryFootprint(models.Model): 
    ISO2 = models.ForeignKey(Country) 
    footprint = models.DecimalField(max_digits=18, decimal_places=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 has no ISO2. 

пытались также:

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 

Я прочитал documentation, и я уверен, что ответ есть, но это просто не прыгает на меня!

+0

просто указывая поля = ('ISO2') в мета-классе CountryFootprintResource doens't работать? – DRC

+0

Пробовал это, TypeError: принуждение к Unicode: нужна строка или буфер, страна найдена снова. Странно, вы бы подумали, что страна будет правильной, и она ищет строку. – PhoebeB

+0

Спасибо за подталкивание DRC, попал туда в конце. – PhoebeB

ответ

4

Любой из этих двух линий работы:

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

или

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

используя только:

fields = ('ISO2', 'footprint') 

дает ошибку

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

принуждающего ошибки Unicode была вызвана тем, что я не имеющий строку, возвращаемую из юникода DEF:

def __unicode__(self): 
    return self.ISO2 

должен был

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

так много проблем кодирования, решаемые хороший ночной сон!

Смежные вопросы