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 при наличии дубликатов данных, это позволит вам обнаружить проблему в представлении и затем отобразить/выдать нужное сообщение об ошибке.

Вернуться на верх