常见问题¶
沟通问题、疑问或建议的最佳方式是什么?¶
要提交功能、报告错误或提问,请参阅我们的 贡献指南。
需要帮忙吗?¶
我们欢迎社区的贡献。
您可以通过以下方式提供帮助:
报告错误或问题。
回答在`Stack Overflow <https://stackoverflow.com/questions/tagged/django-import-export/>`_上或作为Github issues出现的问题。
为UI文本提供翻译。
建议功能或更改。
我们鼓励您阅读:doc:贡献指南 <contributing>。
常见问题¶
import_id_fields 导入错误¶
导入时可以看到以下错误信息:
以下字段在'import_id_fields'中声明但未出现在资源中
这表明该资源未正确配置,导入逻辑失败。具体而言,导入过程尝试使用为`:attr:~import_export.options.ResourceOptions.import_id_fields`定义的或默认的值,但在资源字段中未检测到匹配的字段。请参阅advanced_usage:创建或更新模型实例。
在您有意使用 import_id_fields 中的生成字段且这些字段未出现在数据集中的情况下,您需要修改资源定义以适应这种情况。请参阅 使用“动态字段”来识别现有实例。
如何处理来自Signals的双重保存¶
如果实现了保存后 信号,并且正在使用 Admin 界面中的导入工作流,则可能会遇到此问题。您会发现每个实例的保存后信号被调用了两次。原因是模型的 save() 方法被调用了两次:一次用于“确认”步骤,一次用于“导入”步骤。在“确认”步骤期间调用 save() 是必要的,以证明对象将成功保存,或在保存失败时在 Admin UI 中报告任何异常。在“确认”步骤之后,数据库事务会回滚,因此不会保留任何更改。
因此目前无法阻止``save()``被调用两次,且总会触发两次信号调用。有一个变通方法,即在被保存的实例上设置临时标志:
class BookResource(resources.ModelResource):
def before_save_instance(self, instance, row, **kwargs):
# during 'confirm' step, dry_run is True
instance.dry_run = kwargs.get("dry_run", False)
class Meta:
model = Book
fields = ('id', 'name')
你的信号接收器可以随后包含条件逻辑来处理此标志:
@receiver(post_save, sender=Book)
def my_callback(sender, **kwargs):
instance = kwargs["instance"]
if getattr(instance, "dry_run"):
# no-op if this is the 'confirm' step
return
else:
# your custom logic here
# this will be executed only on the 'import' step
pass
如何动态设置resource值¶
在某些用例中,您可能需要将运行时或用户提供的值传递给Resource。请参阅 如何动态设置resource值。
如何在持久化之前为所有导入的实例设置值¶
如果需要在导入期间创建的每个实例上设置相同的值,请参考 advanced_usage:如何在持久化之前为所有导入的实例设置值。
如何从多个表中导出¶
在通常的配置中,一个``Resource``映射到单个模型。如果你想导出与该模型关联的关系数据,那么这些值可以在``fields``声明中定义。参见:ref:advanced_usage:Model relations。
如何在excel单元格中导入imagefield¶
请参考 此问题。
如何在UI错误消息中隐藏堆栈跟踪¶
请参考 如何格式化UI错误消息。
导入期间ID递增了两次¶
使用Admin站点导入时,导入实例的ID可能与预览步骤中显示的ID不同。这是因为行是在'confirm'期间导入的,然后在确认步骤之前事务被回滚。数据库实现意味着序列号可能不会被重复使用。
考虑启用 IMPORT_EXPORT_SKIP_ADMIN_CONFIRM 作为临时解决方案。
查看 此问题 获取更详细的讨论。
非空约束在导入空白CharField时失败¶
这是v3中的一个问题,已在v4中解决。该问题在从Excel导入时出现,因为空单元格在导入过程中被转换为``None``。如果导入过程尝试保存null值,则会引发'NOT NULL'异常。
在 v4 中,初始化检查会查看 Django 的 CharField 是否将 blank 设置为 True。如果是,则 null 值或空字符串将作为空字符串持久化。
如果需要持久化 None 而非空字符串,则可以将 allow_blank 小部件参数设置为:
class BookResource(resources.ModelResource):
name = Field(widget=CharWidget(allow_blank=False))
class Meta:
model = Book
查看 此问题。
导入时外键为空¶
可以通过定义带有双下划线语法的字段来引用模型关系。例如:
fields = ("author__name")
这意味着在导出期间,将遵循该关系,并且被引用的字段将被正确添加到导出中。
这在导入期间不起作用,因为引用可能不足以识别正确的关系实例。在导入时应使用 ForeignKeyWidget。请参阅解释 外键关系 的文档。
如何自定义导出数据¶
查看StackOverflow上的以下回答:
https://stackoverflow.com/questions/74802453/仅导出用户注册的数据-django-import-export
如何自定义Excel导出数据¶
如果你想在导出到Excel时对导出数据的格式有更多控制,可以编写一个自定义格式,该格式使用`openpyxl API <https://openpyxl.readthedocs.io/en/stable/>`_。参见示例`here <https://github.com/django-import-export/django-import-export/issues/2085#issuecomment-3096872093>`_。
如何设置导出文件编码¶
如果导出产生乱码或意外输出,您可能需要设置导出编码。参见 this issue。
如何在导入时创建不存在的关系¶
参见 创建不存在的关联。
如何处理大型文件导入¶
如果上传大文件,可能会遇到超时。参见 Using celery 和 批量导入。
导入期间的性能问题或意外行为¶
这可能是由于Excel文件中的隐藏行。隐藏行可以使用:ref:`import_export_import_ignore_blank_lines`排除。
参考 此PR 获取更多信息。
如何在 Foreign Key 查找中使用 id 以外的字段¶
参见 advanced_usage:外键关系。
日志中出现“failed to assign change_list_template attribute”警告¶
这表明change_list_template属性无法设置,很可能是由于与第三方库冲突。参考:ref:interoperability。
如何在导入过程中跳过带有验证错误的行¶
参考 此评论。
在管理员导入“confirm”步骤期间的``FileNotFoundError``¶
在导入过程中您可能会遇到错误,例如:
FileNotFoundError [Errno 2] No such file or directory: '/tmp/tmp5abcdef'
这通常是因为您在多服务器或容器环境中运行管理站点。在导入过程中,导入文件必须临时存储,然后在确认后检索以进行存储。因此可能会出现``FileNotFoundError``错误,因为确认后服务器进程无法访问临时存储。
要解决此问题,您应避免在多服务器环境中使用临时文件系统存储。
请参阅 导入确认 获取更多信息。
如何导出大型数据集¶
大型数据集可以通过多种方式导出,具体取决于数据大小和偏好。
你可以编写自定义脚本或`Admin命令<https://docs.djangoproject.com/en/stable/howto/custom-management-commands/>`_来处理导出。输出可以写入本地文件系统、云存储桶、网络存储等。请参阅关于:ref:`以编程方式导出<exporting_data>`的文档。
你可以使用第三方库 django-import-export-celery 来处理长时间运行的导出。
你可以启用 通过管理员操作导出 然后在 Admin UI 中逐页选择要导出的项目。如果你有相对较少的页面并且可以处理导出到多个文件,这将有效。此方法适合一次性使用或作为通过 Admin UI 导出大型数据集的简单方式。
如何在导出时更改列名¶
如果你想在导出时修改列名,可以通过重写 get_export_headers() 来实现:
class BookResource(ModelResource):
def get_export_headers(self, fields=None):
headers = super().get_export_headers(fields=fields)
for i, h in enumerate(headers):
if h == 'name':
headers[i] = "NEW COLUMN NAME"
return headers
class Meta:
model = Book
如何配置日志记录¶
请参阅 日志配置 获取更多信息。
导出到Excel时出现``IllegalCharacterError``¶
当您的数据包含无法在Excel中呈现的字符时,会发生这种情况。您可以配置导入导出以 清理这些字符。