Home > Blockchain >  django import-export composite foreign key
django import-export composite foreign key

Time:05-13

I Have two models: ExternalListSettings and PriorityToolPartner. PriorityToolPartner has ForeignKey to ExternalListSettings. ExternalListSettings has complex primary key: import_date partner.

Csv file looks like this:

import_date, partner, hotel_name, slug, bookings, num_in_sortorder

How can i import PriorityToolPartner and combine ['import_date', 'partner'] into ForeignKey to ExternalListSettings model?

Here are my models:

class ExternalListSettings(DiModel):

    class Meta:
        verbose_name_plural = "External List Settings"
        unique_together = ['import_date', 'partner']

    import_date = models.DateField(
        blank=False,
        null=False,
    )
    partner = models.CharField(
        max_length=200,
        blank=False,
        null=False,
    )
    is_top = models.BooleanField(
        blank=True,
        null=False,
        default=False,
    )


class PriorityToolPartner(DiModel):
    
    setting = models.ForeignKey(
        ExternalListSettings,
        null=False,
        blank=False,
        on_delete=models.CASCADE,
        default=0,
    )
    hotel_name = models.CharField(
        max_length=200,
        blank=False,
        null=False,
    )
    slug = models.CharField(
        max_length=300,
        blank=False,
        null=False,
    )
    bookings = models.IntegerField(
        blank=True,
        null=True,
    )
    num_in_sortorder = models.IntegerField(
        blank=True,
        null=True,
    ) 

CodePudding user response:

Potentially you could do this by subclassing ForeignKeyWidget.

class CompositeForeignKeyWidget(widgets.ForeignKeyWidget):

    def clean(self, value, row=None, **kwargs):
        k1 = row["import_date"]
        k2 = row["partner"]
        return self.model.objects.get(import_date=k1, partner=k2)


class PriorityToolPartnerResource(ModelResource):
    setting = Field(widget=CompositeForeignKeyWidget(ExternalListSettings))

    class Meta:
        model = PriorityToolPartner

CodePudding user response:

First of all, I've modified csv file by adding setting field:

import_date, partner, hotel_name, slug, bookings, num_in_sortorder, setting

and left setting blank.

My admin.py:

class CompositeForeignKeyWidget(widgets.ForeignKeyWidget):

    def clean(self, value, row=None, **kwargs):
        k1 = row["import_date"]
        k2 = row["partner"]
        return self.model.objects.get(import_date=k1, partner=k2)

class PriorityToolPartnersResource(resources.ModelResource):
    setting = Field(
        attribute='setting',
        widget=CompositeForeignKeyWidget(ExternalListSettings)
    )

    class Meta:
        model = PriorityToolPartner
        skip_unchanged = True
        report_skipped = True
        exclude = ('id',)
        import_id_fields = (
            'import_date',
            'partner',
            'hotel_name',
            'slug',
            'bookings',
            'num_in_sortorder',
        )
        fields = (
            'setting',
            'hotel_name',
            'slug',
            'bookings',
            'num_in_sortorder',
        )

    def get_import_fields(self):
        return [self.fields[f] for f in ['setting', 'hotel_name', 'slug', 'bookings', 'num_in_sortorder']]

Make sure foreign key field is represented in row before

self.import_obj(instance, row, dry_run, **kwargs)

I made it by modifying csv file and adding setting to fields

  • Related