Search code examples
djangodjango-import-export

Customize admin import forms


I want to add an additional field to my Import-Form on the Admin page. I did everything the Docs say but the entered values for year and calender_week wont show up.

resources.py

class ForecastListResource(resources.ModelResource):
    year = fields.Field(column_name="Jahr", attribute="year")
    calender_week = fields.Field(column_name="Kalenderwoche", attribute="calender_week")
    brand = fields.Field(column_name="Marke", attribute="brand")
    material = fields.Field(column_name="Material", attribute="material")
    material_short_text = fields.Field(column_name="Materialkurztext", attribute="material_short_text")
    gmc = fields.Field(column_name="GMC", attribute="gmc")
    gmc_text = fields.Field(column_name="GMC Text", attribute="gmc_text")
    bed_date = fields.Field(column_name="BedTermin", attribute="bed_date")
    bed_amount = fields.Field(column_name="BedMenge", attribute="bed_amount")
    bed_week = fields.Field(column_name="BedWoche", attribute="bed_week")
    code_last_bed_week = fields.Field(column_name="Code letzte KW", attribute="code_last_bed_week")
    fabric_number = fields.Field(column_name="Stoffnummer", attribute="fabric_number")
    print_stage_3 = fields.Field(column_name="Druckstufe 3", attribute="print_stage_3")
    average_filling = fields.Field(column_name="Mittelwert Abfüllung", attribute="average_filling")
    net = fields.Field(column_name="Netto", attribute="net")

    class Meta:
        model = ForeCastList
        use_bulk = True
        skip_unchanged = True

forms.py

class ForecastDoDImportFormMixin(forms.Form):
    calender_week = forms.IntegerField(label="Kalenderwoche", required=True)
    year = forms.IntegerField(label="Jahr", required=True)


class ForecastDoDImportForm(ForecastDoDImportFormMixin, ImportForm):
    pass


class ForecastDoDConfirmImportForm(ForecastDoDImportFormMixin, ConfirmImportForm):
    pass

admin.py

@admin.register(ForeCastList)
class ForeCastList(ImportExportModelAdmin):
    resource_class = ForecastListResource

    def get_import_form(self):
        return ForecastDoDImportForm

    def get_confirm_import_form(self):
        return ForecastDoDConfirmImportForm

    def get_form_kwargs(self, form, *args, **kwargs):
        if isinstance(form, ForecastDoDImportForm):
            if form.is_valid():
                kwargs.update({"calender_week": form.cleaned_data["calender_week"], "year": form.cleaned_data["year"]})
        return kwargs

    def get_import_data_kwargs(self, request, *args, **kwargs):
        print(kwargs)
        return super().get_import_data_kwargs(request, *args, **kwargs)

Import-Form

Result

-> related Part from the Doc´s: https://django-import-export.readthedocs.io/en/latest/getting_started.html#customize-admin-import-forms


Solution

  • If I understand correctly, you want to select a value from a dropdown and have that inserted for all rows. This means that if there is a value for 'Jahr' in the import file, this will be ignored in favour of the value selected from the dropdown.

    Setting an import field to the selection in the dropdown can be achieved by assigning the value of the dropdown onto the instance of the object to be imported as follows. (I've used the single field 'year' instead of 'Jahr' and 'Kalenderwoche' but you can update your implementation along the same lines).

    class ForecastListResource(resources.ModelResource):
        year = fields.Field(column_name="Jahr", attribute="year")
        # (other fields removed for brevity
    
        def after_import_instance(self, instance, new, row_number=None, **kwargs):
            # override to set the value of the dropdown onto the row instance
            instance.year = kwargs.get("year")
    
        class Meta:
            model = ForeCastList
            use_bulk = True
            skip_unchanged = True
    

    Declare the ModelAdmin class to read the 'year' value from the form:

    @admin.register(ForeCastList)
    class ForeCastList(ImportExportModelAdmin):
        resource_class = ForecastListResource
    
        # other methods removed
    
        def get_import_data_kwargs(self, request, *args, **kwargs):
            form = kwargs.get('form')
            if form:
                return {"year": form.cleaned_data["year"]}
            return dict()
    

    I was able to complete this in the example app:

    example of book import with year field