我正在使用django import-export和ImportExportModelAdmin
从管理界面将数据从文件导入数据库。
以下是我使用的模型资源:
class ImportedBetResource(resources.ModelResource):
date = fields.Field(column_name='Date',
attribute='date',
widget=DateWidget(format="%d/%m/%Y"))
time = fields.Field(column_name='Time',
attribute='time',
widget=TimeWidget(format="%H:%M"))
sport = fields.Field(column_name='Sport',
attribute='sport',
widget=ForeignKeyWidget(Sport, 'name'))
country = fields.Field(column_name='Country',
attribute='country',
widget=ForeignKeyWidget(Country, 'name'))
bookie = fields.Field(column_name='Bookie',
attribute='bookie',
widget=ForeignKeyWidget(Bookie, 'name'))
currency = fields.Field(column_name='Currency',
attribute='stake_currency',
widget=ForeignKeyWidget(Currency, 'name'))
odds = fields.Field(column_name="Odds",
attribute="odds",
widget=DecimalWidget())
status = fields.Field(column_name='Status',
attribute='status',
widget=ForeignKeyWidget(Status, 'name'))
class Meta:
model = Bet
fields = ("id", "date", "time", "sport",
"country",
"competition", "home",
"visitor",
"bookie", "bet", "stake",
"currency",
"odds", "status")
clean_model_instances = True
@classmethod
def field_from_django_field(self, field_name, django_field, readonly):
"""
Returns a Resource Field instance for the given Django model field.
"""
FieldWidget = self.widget_from_django_field(django_field)
widget_kwargs = self.widget_kwargs_for_field(field_name)
field = fields.Field(attribute=field_name, column_name=field_name.replace("__name", "").title(),
widget=FieldWidget(**widget_kwargs), readonly=readonly)
return field
这是来自documentation的导入视图的屏幕截图:
您可以看到文本“此导入程序将导入以下字段”,后跟字段名称。
就我而言,显式定义的字段首先出现,例如:
country = fields.Field(column_name='Country',
attribute='country',
widget=ForeignKeyWidget(Country, 'name'))
,然后是class Meta fields
中定义的其余字段:
This importer will import the following fields: Date, Time, Sport, Country, Bookie, Currency, Odds, Status, Id, Competition, Home, Visitor, Bet, Stake
问题在于字段的顺序不符合文件中字段的顺序,并且数据变得混乱。
仅当文件中有错误时才会发生。
答案 0 :(得分:2)
将export_order选项添加到资源的Meta字段中,如下所示:
class Meta:
model = Bet
fields = ("id", "date", "time", "sport",
"country",
"competition", "home",
"visitor",
"bookie", "bet", "stake",
"currency",
"odds", "status")
clean_model_instances = True
export_order = ["Date", "Time", "Sport", "Country",
"Bookie", "Currency", "Odds", "Status",
"Id", "Competition", "Home", "Visitor",
"Bet", "Stake"]
(或以您想要的任何首选顺序)和django-import-export将相应地导入您声明的字段!之所以可行,是因为get_fields()调用了export_order,而get_import_fields()和get_export_fields()又调用了该命令,从而影响了两个流程的整个工作流程。
def export_order = None
def get_fields(self, **kwargs):
"""
Returns fields sorted according to
:attr:`~import_export.resources.ResourceOptions.export_order`.
"""
return [self.fields[f] for f in self.get_export_order()]
def get_import_fields(self):
return self.get_fields()
def get_export_fields(self):
return self.get_fields()
def import_obj(self, obj, data, dry_run):
"""
Traverses every field in this Resource and calls
:meth:`~import_export.resources.Resource.import_field`. If
``import_field()`` results in a ``ValueError`` being raised for
one of more fields, those errors are captured and reraised as a single,
multi-field ValidationError."""
errors = {}
for field in self.get_import_fields():
if isinstance(field.widget, widgets.ManyToManyWidget):
continue
try:
self.import_field(field, obj, data)
except ValueError as e:
errors[field.attribute] = ValidationError(
force_text(e), code="invalid")
if errors:
raise ValidationError(errors)
上面是import_export.resources.py的摘录。为了进一步说明,我还建议导入数据工作流documentation和import_export的resources的方法。
我希望这会有所帮助!