2👍
The issue is that your ’email’ field is being treated as a lookup key and not an email address. This can be resolved by customizing ForeignKeyWidget
to add email validation.
What is happening is that you are importing an investment resource, which might be something like:
email,firstname,lastname
bob@example.com,bob,smith
You have configured InvestmentResource
to use the email as a lookup key for Profile
. This means that django-import-export
is not going to process it as an email address, but instead as lookup key for Profile
, so in the code (ForeignKeyWidget
) it will be doing something like:
Profile.objects.get(email='bob@example.com')
If this is successful, your Investment
instance will now have the correct profile as a foreign key reference.
This will raise a DoesNotExist
exception if the associated Profile
is not present. Therefore you can argue that an email address sent in the csv must be valid, because it if is not then no lookup will be possible.
However, if you want to check that an email is syntactically valid before you attempt to load the Profile
, then this is easy to do, you need to override ForeignKeyWidget
to perform validation first:
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
class ValidatingForeignKeyWidget(widgets.ForeignKeyWidget):
def clean(self, value, row=None, *args, **kwargs):
try:
validate_email(value)
except ValidationError as e:
# a quirk of import-export means that the ValidationError
# should be re-raised
raise ValueError(f"invalid email {e}")
try:
val = super().clean(value)
except self.model.DoesNotExist:
raise ValueError(f"{self.model.__name__} with value={value} does not exist")
return val