IntegrityError в дублированном ключе django
Здравствуйте, у меня есть простая форма на django, я пытаюсь заставить ее возвращать простое сообщение об ошибке, говорящее: "этот сотрудник уже существует", но на данный момент приложение просто падает всякий раз, когда я это делаю, валидация нацелена на поле email формы, для этого я использовал поле email по умолчанию, которое поставляется с методом get_user_model из django, и с тех пор я добавил обычное поле email в модель, но результаты те же.
Вот моя форма:
class EmployeeForm(Form):
first_name = CharField(max_length=40, label=_('Nombre'))
last_name = CharField(max_length=40, label=_('Apellido'))
children = IntegerField(label=_('Cantidad de Hijos'), required=False)
email2 = EmailField(label=_('Correo electrónico personal'), required=False)
email = EmailField(label=_('Correo electrónico Corporativo'))
company = ModelChoiceField(queryset=Company.objects.all(), required=False, label=_('Empleado de'))
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList,
label_suffix=None, empty_permitted=False, user=None):
super().__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted)
if not user.is_staff:
self.fields['company'].queryset = Company.objects.filter(id=user.employee.company.id)
def clean(self):
cd = super(EmployeeForm, self).clean()
email = cd.get('email2', None)
try:
obj = Employee.objects.get(email__iexact=email.lower().strip())
if self.instance and not obj == self.instance:
raise ValidationError(_('Ya existe un empleado con ese email'),
code='not_unique_in_province')
except Employee.DoesNotExist:
pass
return cd
моя модель:
class Employee(models.Model):
user = models.OneToOneField(User, verbose_name=_('Usuario'), on_delete=models.CASCADE)
name = models.CharField(max_length=100, default=' ', verbose_name=_('nombre'))
auth_code = models.CharField(max_length=5, verbose_name=_('Codigo autorizacion'))
children = models.IntegerField(null=True, blank=True, default=0, verbose_name=_('Hijos'))
email = models.EmailField(null=True, blank=True, verbose_name=_('Correo electrónico corporativo'))
email2 = models.EmailField(null=True, blank=True, verbose_name=_('Correo electrónico personal'))
company = models.ForeignKey(Company, related_name='employes', null=True, verbose_name=_('Empresa'), on_delete=models.CASCADE)
class Meta:
permissions = (('corporate_access', 'Corporate clients access permission'),)
def __str__(self):
return '{} {} ({})'.format(self.user.first_name, self.user.last_name, self.email)
def is_agent(self):
if self.company_supervised:
return True
return False
def full_name(self):
return '{} {}'.format(self.user.first_name, self.user.last_name)
и мое мнение:
class EmployeeCreateUpdateView(generic.FormView):
template_name = 'oscar/dashboard/company/employee_form.html'
form_class = forms.EmployeeForm
def get_context_data(self, *args, **kwargs):
ctx = super(EmployeeCreateUpdateView, self).get_context_data(
*args, **kwargs)
ctx["title"] = self.get_title()
return ctx
class EmployeeCreateView(EmployeeCreateUpdateView):
def get_title(self):
return _("Agregar un empleado")
def get_form_kwargs(self):
kw = super().get_form_kwargs()
kw.update({'user': self.request.user})
return kw
def get_success_url(self):
messages.info(self.request, _("Empleado creado exitosamente"))
return reverse("dashboard:company:employee-list")
def form_valid(self, form):
email = form.cleaned_data['email']
company = form.cleaned_data.get('company', None)
fn = form.cleaned_data['first_name']
ln = form.cleaned_data['last_name']
child = form.cleaned_data['children']
email2 = form.cleaned_data['email2']
name = email
auth = ''.join(random.choice('0123456789abcdefghijklmnopqrstuvwxyz') for i in range(5))
try:
user = User.objects.get(email=email)
user.set_password(auth)
user.first_name = fn
user.last_name = ln
user.children = child
user.email2 = email2
user.name = name
user.save()
Employee.objects.create(user=user, company=company, auth_code=auth, children=child, email2=email2, name=name,)
except User.DoesNotExist:
user = User.objects.create_user(username=name, email=email, password=auth, first_name=fn, last_name=ln)
Employee.objects.create(user=user, company=company, auth_code=auth, children=child, email2=email2, name=name,)
return super().form_valid(form)
что я делаю не так?
Вы можете добиться желаемого поведения, используя метод clean. Этот метод присутствует как в самом определении Field, так и в определениях Form.
Более подробную информацию вы можете найти в документации Django:
Вызывая ValidationError при наличии дубликатов данных, это позволит вам обнаружить проблему в представлении и затем отобразить/выдать нужное сообщение об ошибке.