gpt4 book ai didi

python - 扩展 django-import-export 的导入表单以指定每个导入行的固定值

转载 作者:太空宇宙 更新时间:2023-11-04 00:11:43 24 4
gpt4 key购买 nike

我在 Django 2.1.1 中使用带有管理集成的 django-import-export 1.0.1。我有两个模型

from django.db import models

class Sector(models.Model):
code = models.CharField(max_length=30, primary_key=True)

class Location(models.Model):
code = models.CharField(max_length=30, primary_key=True)
sector = ForeignKey(Sector, on_delete=models.CASCADE, related_name='locations')

并且可以使用模型资源很好地导入/导出它们

from import_export import resources
from import_export.fields import Field
from import_export.widgets import ForeignKeyWidget

class SectorResource(resources.ModelResource):
code = Field(attribute='code', column_name='Sector')
class Meta:
model = Sector
import_id_fields = ('code',)

class LocationResource(resources.ModelResource):
code = Field(attribute='code', column_name='Location')
sector = Field(attribute='sector', column_name='Sector',
widget=ForeignKeyWidget(Sector, 'code'))
class Meta:
model = Location
import_id_fields = ('code',)

导入/导出操作可以通过

集成到管理中
from django.contrib import admin
from import_export.admin import ImportExportModelAdmin

class SectorAdmin(ImportExportModelAdmin):
resource_class = SectorResource

class LocationAdmin(ImportExportModelAdmin):
resource_class = LocationResource

admin.site.register(Sector, SectorAdmin)
admin.site.register(Location, LocationAdmin)

对于 Reasons™,我想更改此设置,以便 Locations 的电子表格包含部门列可以进口; sector 的值(对于每个导入的行)应该从管理中 ImportForm 的额外字段中获取。

这样的字段确实可以通过覆盖 ModelAdmin 上的 import_action 来添加,如 Extending the admin import form for django import_export 中所述。 .下一步,将此值用于所有导入的行,那里缺少,我一直无法弄清楚如何去做。

最佳答案

EDIT(2):通过使用 session 解决。拥有一个 get_confirm_import_form 钩子(Hook)仍然在这里确实有帮助,但更好的是让现有的 ConfirmImport_Form 携带所有提交的字段和值初始导入表单。

编辑: 抱歉,我以为我已经解决了这个问题,但我自己的代码并没有像我想象的那样工作。这没有解决在 ConfirmImportForm 中传递 sector 表单字段的问题,这是完成导入所必需的。目前正在寻找一种不涉及将整个 import_action() 粘贴到 ImportMixin 子类中的解决方案。有一个 get_confirm_import_form() Hook 在这里会有很大帮助。

仍在为自己寻找解决方案,当我有一个解决方案时,我也会更新它。


不要覆盖 import_action。这是一个你不想复制的大而复杂的方法。更重要的是,正如我今天发现的那样:有更简单的方法可以做到这一点。

首先(如您所述),为 Location 创建一个自定义导入表单,允许用户选择 Sector:

class LocationImportForm(ImportForm):
sector = forms.ModelChoiceField(required=True, queryset=Sector.objects.all())

在资源 API 中,有一个 before_import_row() Hook ,每行调用一次。因此,在您的 LocationResource 类中实现它,并使用它来添加 Sector 列:

def before_import_row(self, row, **kwargs):
sector = self.request.POST.get('sector', None)
if contract:
self.request.session['import_context_sector'] = sector
else:
# if this raises a KeyError, we want to know about it.
# It means that we got to a point of importing data without
# contract context, and we don't want to continue.
try:
sector = self.request.session['import_context_sector']
except KeyError as e:
raise Exception("Sector context failure on row import, " +
f"check resources.py for more info: {e}")
row['sector'] = sector

(注意此代码使用 Django session 将 sector 值从导入表单传送到导入确认屏幕。如果您不使用 session ,则您我们需要找到另一种方法来做到这一点。)

这就是您获取额外数据所需的全部内容,它适用于试运行预览和实际导入。

请注意 self.request 不存在于默认的 ModelResource 中 - 我们必须通过为 LocationResource 提供自定义构造函数来安装它:

def __init__(self, request=None):
super()
self.request = request

(不要担心 self.request 会一直存在。每个 LocationResource 实例都不会在单个请求之后持续存在。)

request 通常不会传递给 ModelResource 构造函数,因此我们需要将其添加到该调用的 kwargs 字典中。幸运的是,Django Import/Export 有一个专门的钩子(Hook)。在 LocationAdmin 中覆盖 ImportExportModelAdminget_resource_kwargs 方法:

def get_resource_kwargs(self, request, *args, **kwargs):
rk = super().get_resource_kwargs(request, *args, **kwargs)
rk['request'] = request
return rk

这就是您所需要的。

关于python - 扩展 django-import-export 的导入表单以指定每个导入行的固定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52335510/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com