django-import-exportでリレーションモデルのフィールドが管理画面上のインポートプレビュー画面に表示されない

発生したこと

django-import-export で、対象のモデル( Example ) に関連付けに必要な列( hoge_id )がプレビューで表示されていない問題がありました。

原因

hoge_id は、対象モデルがもつ実際のフィールドではなく、インポート処理でのみ使用するフィールドでした。

かつリレーションもdjango.db.models.ForeignKey で辿れず、より深いものだったので import_export.widgets.ForeignKeyWidget を指定するだけでは実現できませんでした。

行ったこと

1. import_export.fields.Fieldのattributeに一時的な属性を付与

_hoge_id_import という一時的なフィールドをattributesに用意し、CSVインポートの値をそこに格納するようにしました。

from import_export import fields, resources

class ExampleResource(resources.ModelResource):
    hoge_id = fields.Field(
        column_name="hoge_id",
        attribute="_hoge_id_import",
    )

2. プレビュー画面での表示

Meta.fields に含めてプレビュー画面の対象とする

class Meta:
    model = Example
    fields = (
        # ... 他のフィールド
        "hoge_id", 

    )

3. 一時属性の削除

import_instance メソッドをオーバーライドして、保存前に一時属性を削除する

def import_instance(self, instance, row, **kwargs):
    if hasattr(obj, '_hoge_id_import'):
        delattr(obj, '_hoge_id_import')
    return super().import_instance(instance, row, **kwargs)

以上の3つの対応をすることでプレビュー画面に表示することができました。

余談

一時的な属性を付与して削除するやり方がちょっとイケてないなぁと思っています。もっとよいやりかたがあれば知りたいです…