Reputation: 341
When importing a file I want to skip all of the new rows that doesn't exist, and only update and change the ones that already exists, I've been trying for days to solve this problem, any ideas will help.
also the file type is ".xls" or ".xlsx"
here's my code:
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
Upvotes: 1
Views: 2966
Reputation: 537
here is the updated version
def skip_row(self, instance, original, row, import_validation_errors=None):
return getattr(original, "pk") is None
Upvotes: 0
Reputation: 2636
The full solution exists here
To only update existing items while ignoring any new item you can use:
# 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)
To import only new items while preventing updates you can use:
# Only import new items. Do not update any record
def skip_row(self, instance, original):
if not original.id:
return False
return True
This assumes import_id_fields = ('id',)
and resource is called BookResource
Upvotes: 1
Reputation: 4306
So if you want to skip any rows in the import file which do not already exist in the database, then you can ignore any rows which don't have a pk (i.e. have not previously been persisted):
Just add the following to your BookResource
sub class
def skip_row(self, instance, original):
return getattr(original, "pk") is None
I hope this works - let me know if I've misunderstood anything.
Upvotes: 1