РЕДАКТИРОВАТЬ (2): Решено с помощью сеансов.Наличие get_confirm_import_form
хука все же действительно поможет в этом, но еще лучше будет иметь существующий ConfirmImportForm
перенос по всем представленным полям и значениям из начальной формы импорта.
РЕДАКТИРОВАТЬ: Извините, я думал, что это было прибито, но мой собственный код не работал, а я думал, что это было.Это не не решает проблему передачи поля формы sector
в ConfirmImportForm
, что необходимо для завершения импорта.В настоящее время ищем решение, которое не включает вставку всего import_action()
в подкласс ImportMixin
.Хук get_confirm_import_form()
очень поможет здесь.
Я все еще работаю над решением для себя, и когда у меня будет его, я тоже обновлю его.
Непереопределить import_action
.Это большой сложный метод, который вы не хотите копировать.Что еще более важно, как я обнаружил сегодня: есть более простые способы сделать это.
Сначала (как вы упомянули) создайте пользовательскую форму импорта для Location
, которая позволяет пользователю выбрать Sector
:
class LocationImportForm(ImportForm):
sector = forms.ModelChoiceField(required=True, queryset=Sector.objects.all())
В Resource API есть хук before_import_row()
, который вызывается один раз для каждой строки.Итак, реализуйте это в своем классе 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 для переноса sector
значение из формы импорта на экран подтверждения импорта. Если вы не используете сеансы, вам нужно найти другой способ сделать это.)
Это все, что вам нужно, чтобы получить дополнительные данные ви он работает как для предварительного пробного запуска, так и для фактического импорта.
Обратите внимание, что self.request
не существует по умолчанию ModelResource
- мы должны установить его, предоставив LocationResource
пользовательскийКонструктор:
def __init__(self, request=None):
super()
self.request = request
(Не беспокойтесь о self.request
, задерживающемся. Каждый экземпляр LocationResource
не сохраняется после одного запроса.)
request
isn 'Обычно t передается конструктору ModelResource
, поэтому нам нужно добавить его в dict kwargs для этого вызова.К счастью, в Django Import / Export есть специальный хук для этого.Переопределите метод ImportExportModelAdmin
get_resource_kwargs
в LocationAdmin
:
def get_resource_kwargs(self, request, *args, **kwargs):
rk = super().get_resource_kwargs(request, *args, **kwargs)
rk['request'] = request
return rk
И это все, что вам нужно.