2015-09-03 4 views
2

Я использую библиотеку импорта-экспорта django для данных. Он работает хорошо, за исключением того, что я не могу заставить его импортировать объекты, которые еще не существуют во внешнем ключе.Django импорт-экспорт новых значений в ключевой модели foriegn

Если объекты (значения в csv) существуют в модели внешнего ключа, то он импортирует штраф.

Но если объекты/значения не существуют в модели внешнего ключа, он говорит, что «соответствующий запрос не существует» и не будет импортировать данные.

Как я могу сказать, чтобы добавить новый объект к модели внешнего ключа, если они не существуют во внешнем ключе?

Models.py фрагмент

class Store(models.Model): 

    store_name = models.CharField(max_length=30) 
    def __unicode__(self): 
     return self.store_name 
    #etc 

class Product(models.Model): 

    Store = models.ForeignKey(Store) 
    Category = models.ForeignKey(Category) 
    first_name = models.CharField(max_length=30) 
    second_name = models.CharField(max_length=30) 
... 

Admin.py фрагмент

admin.site.register(Category) 
admin.site.register(Store) 

class ProductResource(resources.ModelResource): 

    store_name = fields.Field(column_name='store_name', attribute='Store', 
         widget=ForeignKeyWidget(Store, 'store_name')) 

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

    class Meta: 
     model = Product 
     fields = ('id', 'first_name', 'second_name','store_name') 
     export_order = ('id', 'second_name', 'first_name') 
     skip_unchanged = False 
     report_skipped = False 
     widgets = { 
       'published': {'format': '%d.%m.%Y'}, 
       } 


class ProductAdmin(ImportExportModelAdmin): 
    resource_class = ProductResource 
    list_display = ('first_name', 'second_name') 

admin.site.register(Product, ProductAdmin) 

ответ

1

В ForeignKeyWidget у вас есть метод

def clean(self, value): 
     val = super(ForeignKeyWidget, self).clean(value) 
     return self.model.objects.get(**{self.field: val}) if val else None 

вы могли бы попытаться изменить это сделатьчто-то вроде get_or_create ...

это должно выглядеть примерно так ...

from import_export.widgets import ForeignKeyWidget 
class MyCustomizationToFKWidget(ForeignKeyWidget): 

     def clean(self, value): 
      val = super(ForeignKeyWidget, self).clean(value) 
      HERE SOME LOGIC OVERRIDEN 
+0

Спасибо, но где же я должен положить его? Это не сработало - 'store_name = fields.Field (column_name = 'store_name', attribute = 'Store', widget = ForeignKeyWidget (Store, 'store_name')) def clean (self, value): val = super (ForeignKeyWidget , self) .clean (значение) return self.model.objects.get (** {self.field: val}), если val else None' – Ycon

+1

@Ycon Я обновил свой ответ, но вы должны ввести 'ЗДЕСЬ НЕКОТОРЫЕ LOGIC' ваш пользовательский 'get_or_create' https://docs.djangoproject.com/en/1.8/ref/models/querysets/#get-or-create – andi

+0

Я не знаком с get_or_create вообще. Я читал документы, это все еще неясно. Можете ли вы привести пример для моих моделей? Я не понимаю, что такое логика. – Ycon

1

При условии ForeignKey вашей модели может быть пустым:

MyForeignKeyName = Models.ForeignKey(<modelclass>,blank=True, null=True) 

Вы можете добавить метод before_import_row() в ваш класс ресурсов:

def before_import_row(self,row) : 
    fieldname = 'MyForeignKeyName' 
    if not(<modelclass>.objects.filter(pk=row[fieldname]).exists()) : 
     # print(row['id'],row[fieldname],'unknown key !') # console log 
     row[fieldname ] = None # or something else.. * 

* .. совместимый остроумие h ваш foreignkey configuration [python None = SQL null]

Я немного новичок в Django, поэтому, возможно, это не лучший способ, но это решает мою проблему.

Существует также кое-что о db_constraint = False, которое может быть добавлено к аргументам ForeignKey (некоторая информация @stackoverflow и @django), но я не нашел своего пути.