Django Проверка внешнего ключа электронной почты
У меня есть этот профильный ресурс:
class ProfileResource(resources.ModelResource):
email = fields.Field(attribute='email',
widget=CharWidget(),
column_name='email')
class Meta:
model = Profile
clean_model_instances = True
import_id_fields = ('email',)
, который проверяет email при создании профиля. Это работает нормально, но когда я использую его в качестве внешнего ключа, например:
class InvestmentResource(resources.ModelResource):
email = fields.Field(attribute='email',
widget=ForeignKeyWidget(Profile, field='email'),
column_name='email')
class Meta:
model = Investment
clean_model_instances = True
import_id_fields = ('id',)
Он больше не подтверждает электронную почту. Я пробовал добавить два виджета, ForeignKeyWidget
и CharWidget
для email на InvestmentResource
, но это не сработало.
Как мне затем подтвердить электронную почту внутри InvestmentResource
?
Что происходит, так это то, что вы импортируете инвестиционный ресурс, который может быть чем-то вроде:
email,firstname,lastname
bob@example.com,bob,smith
Вы настроили InvestmentResource
на использование электронной почты в качестве ключа поиска для Profile
. Это означает, что django-import-export
будет обрабатывать его не как адрес электронной почты, а как ключ поиска для Profile
, поэтому в коде (ForeignKeyWidget
) он будет делать что-то вроде:
Profile.objects.get(email='bob@example.com')
Если все прошло успешно, ваш экземпляр Investment
теперь будет иметь правильный профиль в качестве ссылки на внешний ключ.
При этом будет возникать исключение DoesNotExist
, если связанное с ним Profile
отсутствует. Поэтому можно утверждать, что адрес электронной почты, отправленный в csv, должен быть действительным, так как в противном случае поиск будет невозможен
Однако, если вы хотите проверить, что письмо действительно до того, как вы попытаетесь загрузить Profile
, то это легко сделать, вам нужно переопределить ForeignKeyWidget
, чтобы сначала выполнить проверку:
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