如果电子邮件存在,django-import-export 更新配置文件
django-import-export update profile if email exists
我的 Profile model
上有这个 unique field
:
email = models.EmailField(max_length=200, unique=True)
我有这个 ProfileResource
:
class ProfileResource(resources.ModelResource):
# associated_issuer = fields.Field(attribute='add_associated_issuer', widget=ManyToManyWidget(Issuer, field='name'), column_name='Associated Issuer')
email = fields.Field(attribute='email',
widget=CharWidget(),
column_name='email')
class Meta:
model = Profile
clean_model_instances = True
import_id_fields = ('id', 'email')
def before_import_row(self, row, row_number=None, **kwargs):
try:
self.email = row["email"]
except Exception as e:
self.email = ""
try:
if row["id"] == '':
row["id"] = None
self.id = row["id"]
except Exception as e:
self.id = None
try:
self.firstname = row["firstname"]
except Exception as e:
self.firstname = ""
try:
self.lastname = row["lastname"]
except Exception as e:
self.lastname = ""
现在,当我尝试从文件导入时,收到此错误:
我需要能够执行 update_or_create
方法,但是我应该在哪里添加该代码?我尝试在 after_import_instance
上执行此操作,但没有成功。
我也试过 import_row
这样的:
def import_row(self, row, instance_loader, using_transactions=True, dry_run=False, **kwargs):
try:
Profile.objects.update_or_create(email=self.email)
except Exception as e:
print(e, file=sys.stderr)
但它产生了这个错误:
Exception Value: 'NoneType' object has no attribute 'import_type'
任何关于修复的见解都将不胜感激。
#try this
email = models.EmailField(max_length=200, unique=True, null=True)
try:
self.email = row["email"]
except Exception as e:
self.email = None
unique=True
也阻止重复的 "",但不阻止 null。
请注意,您的 ProfileResource
上有此行
import_id_fields = ('id', 'email')
这意味着导入将查看导入文件中的每一行,并尝试加载匹配 id
和 email
的任何 Profile
个实例。
因此,如果您只需要更新 email
,那么只需将其从 import_id_fields
的列表中删除即可。通过这样做,逻辑将仅基于 id
来唯一标识实例,然后如果新记录不存在则将创建新记录,并且将更新任何现有记录(包括更新电子邮件地址)。
这就是 import-export
的工作方式,不需要进一步的逻辑。
如果 email
是匹配您现有实例的“唯一字段”,那么这应该是 import_id_fields
中的唯一字段。不能有两个 Profile
实例具有相同的电子邮件,因为 unique=True
,因此您可以使用 email
作为 import_id_field
。但是,将无法使用 import-export
更新 Profile
电子邮件(尽管您可以引入一个名为 new_email
的字段并具有以这种方式更新 Profile
的逻辑,但是是一个单独的主题)。
我不知道您为什么会看到 'email already exists' 错误 - 可能是其他原因造成的,可能是 before_import_row()
中的逻辑导致了问题,可能是由于使用空字符串作为电子邮件创建行的事实。
顺便说一句 - 你不应该需要 before_import_row()
中的任何逻辑 - import-export
应该为你处理这个,并且通过覆盖你可能会引入更多的错误。
使用 import-export
的最佳建议是在 IDE 中设置断点,然后在导入过程中单步执行,您可以准确地看到发生了什么。这将在漫长的 运行.
中为您节省大量时间
总而言之,在 import_id_fields
中使用 id
或 email
应该可以。
你应该尝试改变
import_id_fields = ('id', 'email')
来自
import_id_fields = ('email',)
当您尝试导入 ID 为空的行时,它将始终被视为新行。所以在这种情况下它会创建而不是更新。但是当你在 import_id_fields
中只留下 email
时,它显然会进行更新而不是创建。
你试过了吗?
我的 Profile model
上有这个 unique field
:
email = models.EmailField(max_length=200, unique=True)
我有这个 ProfileResource
:
class ProfileResource(resources.ModelResource):
# associated_issuer = fields.Field(attribute='add_associated_issuer', widget=ManyToManyWidget(Issuer, field='name'), column_name='Associated Issuer')
email = fields.Field(attribute='email',
widget=CharWidget(),
column_name='email')
class Meta:
model = Profile
clean_model_instances = True
import_id_fields = ('id', 'email')
def before_import_row(self, row, row_number=None, **kwargs):
try:
self.email = row["email"]
except Exception as e:
self.email = ""
try:
if row["id"] == '':
row["id"] = None
self.id = row["id"]
except Exception as e:
self.id = None
try:
self.firstname = row["firstname"]
except Exception as e:
self.firstname = ""
try:
self.lastname = row["lastname"]
except Exception as e:
self.lastname = ""
现在,当我尝试从文件导入时,收到此错误:
我需要能够执行 update_or_create
方法,但是我应该在哪里添加该代码?我尝试在 after_import_instance
上执行此操作,但没有成功。
我也试过 import_row
这样的:
def import_row(self, row, instance_loader, using_transactions=True, dry_run=False, **kwargs):
try:
Profile.objects.update_or_create(email=self.email)
except Exception as e:
print(e, file=sys.stderr)
但它产生了这个错误:
Exception Value: 'NoneType' object has no attribute 'import_type'
任何关于修复的见解都将不胜感激。
#try this
email = models.EmailField(max_length=200, unique=True, null=True)
try:
self.email = row["email"]
except Exception as e:
self.email = None
unique=True
也阻止重复的 "",但不阻止 null。
请注意,您的 ProfileResource
import_id_fields = ('id', 'email')
这意味着导入将查看导入文件中的每一行,并尝试加载匹配 id
和 email
的任何 Profile
个实例。
因此,如果您只需要更新 email
,那么只需将其从 import_id_fields
的列表中删除即可。通过这样做,逻辑将仅基于 id
来唯一标识实例,然后如果新记录不存在则将创建新记录,并且将更新任何现有记录(包括更新电子邮件地址)。
这就是 import-export
的工作方式,不需要进一步的逻辑。
如果 email
是匹配您现有实例的“唯一字段”,那么这应该是 import_id_fields
中的唯一字段。不能有两个 Profile
实例具有相同的电子邮件,因为 unique=True
,因此您可以使用 email
作为 import_id_field
。但是,将无法使用 import-export
更新 Profile
电子邮件(尽管您可以引入一个名为 new_email
的字段并具有以这种方式更新 Profile
的逻辑,但是是一个单独的主题)。
我不知道您为什么会看到 'email already exists' 错误 - 可能是其他原因造成的,可能是 before_import_row()
中的逻辑导致了问题,可能是由于使用空字符串作为电子邮件创建行的事实。
顺便说一句 - 你不应该需要 before_import_row()
中的任何逻辑 - import-export
应该为你处理这个,并且通过覆盖你可能会引入更多的错误。
使用 import-export
的最佳建议是在 IDE 中设置断点,然后在导入过程中单步执行,您可以准确地看到发生了什么。这将在漫长的 运行.
总而言之,在 import_id_fields
中使用 id
或 email
应该可以。
你应该尝试改变
import_id_fields = ('id', 'email')
来自
import_id_fields = ('email',)
当您尝试导入 ID 为空的行时,它将始终被视为新行。所以在这种情况下它会创建而不是更新。但是当你在 import_id_fields
中只留下 email
时,它显然会进行更新而不是创建。
你试过了吗?