Django import-export - Импорт модели с дочерними элементами из excel

У меня есть две модели: Project и Activity.
При регистрации проекта можно добавить одну или несколько связанных с ним работ.

Как я могу импортировать проекты из xlsx, которые включают хотя бы одну деятельность? Я использую стороннюю библиотеку django-import-export

Я настраиваю ресурс проекта на экспорт всех видов деятельности каждого проекта в одну ячейку, разделенную /, но мне нужно наоборот, импортировать все виды деятельности каждого проекта. Я думаю, что сначала я должен сохранить Project для получения id, затем извлечь информацию из ячейки и, наконец, сохранить каждую связанную с ней деятельность, но я не знаю, как это сделать.

Мои упрощенные модели таковы:

class Project(models.Model):
    reg_date= models.DateField(
        default=date.today)
    name = models.CharField(
        max_length=100, 
        unique=True)

    def __str__(self):
        return self.name

class Activity(models.Model):
    schedule= models.ForeignKey(
        Project, 
        on_delete=models.CASCADE)
    date = models.DateField()
    description = models.TextField(max_length=1000)

    class Meta:
        unique_together = ('schedule', 'date', 'description')

class ProjectResource(resources.ModelResource):
    activities = Field()

    class Meta:
        model = Project
        import_id_fields = ['name']
        exclude = ('id',)
        skip_unchanged = True
        report_skipped = True
        fields = ('reg_date',
            'name',
            'activities')
        
    def dehydrate_activities(self, obj):
        if obj.id:
            return "/".join([
                '({0} - {1})'.format(activity.date, activity.description) for activity in obj.projectactivity_set.all()
            ])

    def skip_row(self, instance, original, row, import_validation_errors=None):
        if original.name:
            return True
        return False

Примером экспортированного файла является:

reg_date name activities
2023-01-10 Project 1 2023-01-12-This is the first activity/2023-01-14-This is the second activity
2023-01-10 Project 2 2023-01-13-This is the first activity/2023-01-15-This is the second activity

Вам необходимо создать Activity экземпляры до создания Project экземпляров.

Затем в своем классе ресурсов Project вы можете определить, что определенное поле предназначено для внешних ключей.

У меня есть пример;

from import_export import fields, resources, widgets

from apps.event.models import Occurrence

from ..models import Token


class TokenResource(resources.ModelResource):
    """ Integrate django-import-export with the Token model """
    occurrence = fields.Field(
        column_name='occurrence',
        attribute='occurrence',
        widget=widgets.ForeignKeyWidget(Occurrence, 'id')
    )

    class Meta:
        fields = (
            'id',
            'occurrence',
            'code',
        )
        model = Token

При использовании ForeignKeyWidget первым аргументом является связанная модель, а вторым - уникальное значение, которое можно использовать для поиска экземпляра. Именно это уникальное значение вы затем помещаете в файл импорта для ссылки на связанные объекты.

И моя модель Token имеет эту связь;

class Token(EnabledMixin, TimestampMixin, models.Model):
    """ Token for event entry. """

    class Meta:
        """ Meta class definition. """
        app_label = 'console'
        verbose_name = _("Token")
        verbose_name_plural = _("Tokens")
        unique_together = ('code', 'occurrence')
        ordering = [
            'id',
        ]

    occurrence = models.ForeignKey(
        to='event.Occurrence',
        verbose_name=_("Event Occurrence"),
        blank=True,
        null=True,
        related_name='tokens',
        on_delete=models.SET_NULL,
    )
Вернуться на верх