如何使用 django import-export 在 admin 中订购导入字段?
How do I order the import fields in admin using django import-export?
我正在使用 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:
的导入视图的屏幕截图
您可以看到文本 "This importer will import the following fields" 后跟字段名称。
在我的例子中,显式定义的字段首先出现,例如:
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
问题是字段的顺序不符合我文件中的字段顺序,数据被打乱。
只有当文件中有错误时才会发生这种情况。
export_order就是答案!
将 export_order 选项添加到资源的元字段中,如下所示:
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 将相应地导入您声明的字段!这样做的原因是 export_order 被 get_fields() 调用,而 get_fields() 又被 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. For further clarification, I would also recommend the import data workflow documentation and methods for import_export's resources。
希望对您有所帮助!
我正在使用 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:
的导入视图的屏幕截图您可以看到文本 "This importer will import the following fields" 后跟字段名称。
在我的例子中,显式定义的字段首先出现,例如:
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
问题是字段的顺序不符合我文件中的字段顺序,数据被打乱。
只有当文件中有错误时才会发生这种情况。
export_order就是答案!
将 export_order 选项添加到资源的元字段中,如下所示:
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 将相应地导入您声明的字段!这样做的原因是 export_order 被 get_fields() 调用,而 get_fields() 又被 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. For further clarification, I would also recommend the import data workflow documentation and methods for import_export's resources。
希望对您有所帮助!