【问题标题】:Django import export - How to skip the new rows, and only update the existed onesDjango import export - 如何跳过新行,只更新现有行
【发布时间】:2020-05-01 18:28:39
【问题描述】:

导入文件时,我想跳过所有不存在的新行,只更新和更改已经存在的行,我已经尝试了几天来解决这个问题,任何想法都会有所帮助。

https://ibb.co/1Gw4Q19

文件类型也是“.xls”或“.xlsx”

这是我的代码:

models.py:

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name


class Category(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name


class Book(models.Model):
    name = models.CharField('Book name', max_length=100)
    author = models.ForeignKey(Author, blank=True, null=True, on_delete=models.CASCADE)
    author_email = models.EmailField('Author email', max_length=75, blank=True)
    imported = models.BooleanField(default=False)
    published = models.DateField('Published', blank=True, null=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    categories = models.ManyToManyField(Category, blank=True)

    def __str__(self):
        return self.name

admin.py:

class BookResource(resources.ModelResource):

    class Meta:
        model = Book
        import_id_field = 'id'
        import_id_fields = ('id',)
        fields = ('id', 'name', 'price',)
        skip_unchanged = True
        report_skipped = True
        dry_run = True


class CustomBookAdmin(ImportMixin, admin.ModelAdmin):
    resource_class = BookResource

    # tried to override it like so but it didn't work
    def skip_row(self, instance, original):
        original_id_value = getattr(original, self._meta.import_id_field)
        instance_id_value = getattr(instance, self._meta.import_id_field)
        if original_id_value != instance_id_value:
            return True
        if not self._meta.skip_unchanged:
            return False
        for field in self.get_fields():
            try:
                if list(field.get_value(instance).all()) != list(field.get_value(original).all()):
                    return False
            except AttributeError:
                if field.get_value(instance) != field.get_value(original):
                    return False
        return True

【问题讨论】:

  • 你能澄清你的问题吗? “我想跳过所有存在的新行,只更新和更改已经存在的行”。新行怎么可能已经存在?如果你能改写一下,那就更清楚了。
  • 对不起“那不存在”,我会编辑我的问题。谢谢。

标签: django django-import-export


【解决方案1】:

因此,如果您想跳过导入文件中数据库中尚不存在的任何行,那么您可以忽略任何没有 pk 的行(即以前没有被持久化):

只需将以下内容添加到您的 BookResource 子类中

def skip_row(self, instance, original):
    return getattr(original, "pk") is None

我希望这可行 - 如果我误解了任何内容,请告诉我。

【讨论】:

  • 感谢您的建议,很遗憾这对我不起作用。
  • 天哪!如果您想尝试解决,请随时添加更多信息
【解决方案2】:

完整的解决方案存在here

仅更新现有项目而忽略您可以使用的任何新项目:

# Do not import any new items. Only update records
def skip_row(self, instance, original):
    if original.id:
        return False
    return super(BookResource, self).skip_row(instance, original)

要在阻止更新的同时仅导入新项目,您可以使用:

# Only import new items. Do not update any record
def skip_row(self, instance, original):
    if not original.id:
        return False
    return True

这假定import_id_fields = ('id',) 并且资源被称为BookResource

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多