简体   繁体   English

Django 进出口 - 进口 model with child from excel

[英]Django import-export - Import model with child from excel

I have two models: Project and Activity .我有两个模型: ProjectActivity
When registering a project, one or more associated activities can be added.注册项目时,可以添加一项或多项相关活动。

How can I import projects from xlsx, which include at least one activity?.如何从至少包含一项活动的 xlsx 导入项目? I'm using the third party library django-import-export我正在使用第三方库django-import-export

I configure the project resource to export all the activities of each project in one cell separated by / , but I need the opposite, import all the activities of each project.我将项目资源配置为将每个项目的所有活动导出到一个由/分隔的单元格中,但我需要相反,导入每个项目的所有活动。 I think that I must first save the Project for obtain the id , next extract the info from cell and finally save each activity associated, but I don't know how to do that.我认为我必须首先保存Project以获取id ,然后从单元格中提取信息,最后保存关联的每个活动,但我不知道该怎么做。

My simplified models are:我的简化模型是:

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

An example of exported file is:导出文件的示例是:

reg_date注册日期 name名称 activities活动
2023-01-10 2023-01-10 Project 1项目一 2023-01-12-This is the first activity/2023-01-14-This is the second activity 2023-01-12-这是第一个活动/2023-01-14-这是第二个活动
2023-01-10 2023-01-10 Project 2项目2 2023-01-13-This is the first activity/2023-01-15-This is the second activity 2023-01-13-这是第一个活动/2023-01-15-这是第二个活动

You need to create the Activity instances before you create the Project instances.您需要在创建Project实例之前创建Activity实例。

Then in your Project resource class you can define that a particular field is for foreign keys.然后在您的Project资源 class 中,您可以定义一个特定字段用于外键。

I've got an example;我有一个例子;

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

When using the ForeignKeyWidget , the first argument is the related model, then the second is a unique value that you can use to lookup the instance.使用ForeignKeyWidget时,第一个参数是相关的 model,然后第二个是可用于查找实例的唯一值。 It's that unique value that you then put in your import file to reference the related objects.这是您随后放入导入文件以引用相关对象的唯一值。

And my Token model has that relationship;而我的Token model有那个关系;

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,
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM