python - 如何使用 django import-export 在 admin 中订购导入字段

我正在使用 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 的导入 View 的屏幕截图:

您可以看到文本“此导入器将导入以下字段”,后跟字段名称。

在我的例子中,显式定义的字段首先出现,例如:

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 .为了进一步说明,我还推荐导入数据工作流程 documentation和 import_export 的方法 resources .

希望对您有所帮助!

关于python - 如何使用 django import-export 在 admin 中订购导入字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54616806/

相关文章:

python - 如何将 Base64 图像字符串从 Flask Python 代码传递到 HTML

python-3.x - 如何从 gensim 模块导入 WordEmbeddingSimilari

scala - 如何找到定义 Scala 隐式的位置?

python - 如何展平嵌套模型? (keras 函数式 API)

amazon-web-services - 是否可以在控制台中编辑 AWS Lambda 层代码?

php - 将 CSS 添加到 DomPDF

angular - 如何使用 typescript 修复 Angular 5 中的 ‘debounc

reactjs - React.HTMLProps 破坏 de

ag-grid - 使用 forEachNode 的行选择非常慢

kubernetes - 在 Kubernetes (GKE) 中的一个节点上组合多个本地 SSD