【问题标题】:How to display Django friendly forms.ValidationError/message.error before form.save?如何在 form.save 之前显示 Django 友好的 forms.ValidationError/message.error?
【发布时间】:2018-08-16 07:28:49
【问题描述】:

我想知道如何在 form.save 之前显示 Django message.error(如果用户收到该错误消息,表单将不会被保存,用户必须再次在表单中填写值)。

我不知道是我把它们放在了错误的地方还是其他什么原因,我绝对可以得到关于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 python-3.x django-models django-forms message


    【解决方案1】:

    使表单提交无效的一般方法是使给定的表单呈现错误。

    您可以向表单发送一些必要的数据并自定义表单的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 }}

    【讨论】:

    • 嗨 Tobias,我收到了 'ProjectForm' object has no attribute 'kwargs' 的错误,因为我必须通过 test = Test.objects.get(pk=self.kwargs['pk']), user_project = list(UserProject.objects.filter(test=test)) 从另一个模型中获取对象
    • 嗨 Tobias,如果我在 forms.py 的 Projectform 上使用 request.POST.get(),也会得到 'ProjectForm' object has no attribute request.......的错误。
    • 嗨@Tobias Lorenz 真的需要你的建议,我不能在forms.py中添加forms.ValidationError,也不能在views.py中添加form.add_error,就像我添加test = Test.objects.get(pk=self.kwargs['pk'])一样在 forms.py 我得到'ProjectForm' object has no attribute 'kwargs' 的错误
    • @Begin2Pip self.kwargs 在表单的init函数中设置。调用super().__init__(*args, **kwargs)后需要添加代码。
    【解决方案2】:

    您不会在form_valid 中执行此操作 - 顾名思义,此时表单已被视为有效。实际上,您根本不会在视图中执行此操作。这种东西属于表单,特别是ProjectForm的clean()方法。在那里你可以用你的信息提出forms.ValidationError;然后视图将做正确的事情并重新显示无效的表单。

    【讨论】:

    • 非常感谢丹尼尔,但似乎 forms.ValidationError 是为程序员而不是为客户读取的,太丑了?
    • 不,这根本不是真的。
    • 嗨丹尼尔,不管我怎么改代码,我总是遇到一个看起来像程序错误的丑陋错误,?我真的需要你的建议,非常感谢你的帮助! ??​​pan>
    • 嗨丹尼尔,真的需要你的建议,我不能在forms.py中添加forms.ValidationError,也不能在views.py中添加form.add_error,就像我添加test = Test时一样。 forms.py 中的 objects.get(pk=self.kwargs['pk']) 我收到“ProjectForm”对象的错误没有属性“kwargs”
    • 如果你在表单中使用 self.kwargs 在 init 方法中定义它。
    【解决方案3】:

    使用 Tobias 上面的答案并在方法中将 pk 作为变量传递

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

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 2011-02-02
      • 2018-06-04
      • 2021-01-30
      • 1970-01-01
      • 2017-08-18
      • 1970-01-01
      • 1970-01-01
      • 2010-12-03
      相关资源
      最近更新 更多