Как отображать удобные для Django формы.ValidationError / message.error перед form.save?

Я хотел бы знать, как отображать Django message.error перед form.save (если пользователь получит это сообщение об ошибке, форма не будет сохранена, пользователь должен снова заполнить значение в форме).

Я не знаю, поместил ли я их в неправильное место или по какой-либо другой причине, я определенно могу получить правильное значение для for loop and if else, но если пользователь work_times> = 8 часов, страница не отображает это сообщение об ошибке, и проект может сохранить как и раньше, но я добавил for loop and if else !! Частичный код views.py выглядит следующим образом:

class ProjectCreateView(CreateView):
    model = Project
    form_class = ProjectForm

    def form_valid(self, form):
        request = self.request
        for u in user_project:
            user_times = int(sum(t['learn_times'] for t in times))
            if user_times >= 8 or int(request.POST.get('learn_times')) + user_times >= 8:
                messages.error(self.request, u.username + "'s learn_times is more than 8 hours, please check!")
            else:
                pass
        project = form.save(commit=False)
        project.save()
        form.save_m2m()

        messages.success(self.request, 'Project created successfully!')
        return super(CoursePermitCreateView, self).form_valid(form)

    def get_success_url(self):
        return reverse('project_change', kwargs = {'pk': self.object.pk})

Большое спасибо за любой совет.

🤔 А знаете ли вы, что...
С Django легко создавать RESTful API с помощью фреймворка Django REST framework.


1
1 839
3

Ответы:

Вы не делаете этого в form_valid - как следует из названия, к этому моменту форма уже считается действительной. Фактически, вы вообще не делаете этого в представлении. Такого рода вещи принадлежат форме, в частности методу clean() ProjectForm. Там вы можете поднять forms.ValidationError своим сообщением; тогда представление сделает правильные действия и повторно отобразит недопустимую форму.


Решено

Общий подход к тому, чтобы сделать отправку формы недействительной, заключается в отображении данной формы с ошибками.

Вы можете либо отправить некоторые необходимые данные в форму, либо настроить метод clean формы ...

import forms

class Projectform(forms.ModelForm):
    def __init__(user_project, request, *args, **kwargs):
        self.user_project = user_project
        self.request = request
        super().__init__(*args, **kwargs)

    def clean(self, *args, **kwargs)
        for u in self.user_project:
            user_times = int(sum(t['learn_times'] for t in times))
            if user_times >= 8 or int(self.request.POST.get('learn_times')) + user_times >= 8:
            raise forms.ValidationError(u.username + "'s learn_times is more than 8 hours, please check!")
        return super().clean(*args, **kwargs)

... или вы можете настроить метод представления form_valid и повторно отобразить форму с новым сообщением об ошибке.

class ProjectCreateView(CreateView):
    model = Project
    form_class = ProjectForm

    def form_valid(self, form):
        request = self.request
        for u in user_project:
            user_times = int(sum(t['learn_times'] for t in times))
            if user_times >= 8 or int(request.POST.get('learn_times')) + user_times >= 8:
                form.add_error('__all__', self.request, u.username + "'s learn_times is more than 8 hours, please check!")
                return super().form_invalid(form)

    messages.success(self.request, 'Project created successfully!')
    return super().form_valid(form)

Ошибки появятся в шаблоне {{ form.non_field_errors }}.


Используя ответ Тобиаса выше и передавая pk в качестве переменной в методе

test=Test.objects.get(pk=self.pk)