我正在使用'django import export'(DIE)来导入和更新一些数据。
导入过程从检查DB中的存在对象开始,按ID字段中的值搜索,如果找不到导入文件中具有ID的行,则将创建新的entre。如何进行“仅更新”方案,如果在DB中找不到“id key”,则会跳过行(不添加新行)?
我的model.py
class Size(models.Model):
id = models.AutoField(unique=True, primary_key=True, null=False, blank=False)
height = models.SmallIntegerField()
width = models.SmallIntegerField()
class Product(models.Model):
id = models.AutoField(unique=True, primary_key=True, null=False, blank=False)
vendor_code = models.CharField(unique=True, max_length=50, null=False, blank=False)
price = models.DecimalField(null=False, blank=False)
size = models.ForeignKey(Size, verbose_name=u'Size')
在resource.py
中class ProductSyncResource(resources.ModelResource):
class Meta:
model = ProductVariant
import_id_fields = ('vendor_code',)
fields = ('vendor_code', 'price',)
export_order = ('vendor_code', 'price', 'status', )
skip_unchanged = True
report_skipped = True
dry_run = True
导入表(xls)
如果找不到vendor_code'Tк-12856'(单元格A3),那么DIE将尝试添加此行,并且:
答案 0 :(得分:1)
最后我通过覆盖skip_row
得到了它。现在,字段可以为“null = False”,并且仅导入具有已知import_id_field
值的行。
class VariantSyncResource(resources.ModelResource):
class Meta:
model = ProductVariant
import_id_field = 'vendor_code'
import_id_fields = ('vendor_code',)
fields = ('vendor_code', 'price', 'status', )
export_order = ('vendor_code', 'price', 'status', )
skip_unchanged = True
report_skipped = False
dry_run = True
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
答案 1 :(得分:0)
如果您不想创建新对象,我认为您需要覆盖ProductSyncResource
内的import_row()
。
然后你可以做if new: return
;
def import_row(self, row, instance_loader, using_transactions=True, dry_run=False, **kwargs):
row_result = self.get_row_result_class()()
try:
self.before_import_row(row, **kwargs)
instance, new = self.get_or_init_instance(instance_loader, row)
self.after_import_instance(instance, new, **kwargs)
if new:
return row_result
else:
row_result.import_type = RowResult.IMPORT_TYPE_UPDATE
row_result.new_record = new
original = deepcopy(instance)
...
根据您对预览错误的评论,请记住这不是应用程序的官方功能,因此您只需遵循堆栈跟踪&解决弹出的问题。我上面的第一个想法看起来像最快的&最简单的方法,但您可以尝试使else
保存save条件对新对象;
elif not new:
with transaction.atomic():
self.save_instance(instance, using_transactions, dry_run)
self.save_m2m(instance, row, using_transactions, dry_run)
diff.compare_with(self, instance, dry_run)