有没有办法在重定向甚至清除消息后控制消息?

Is there a way to control the messages after redirect or even clear messages?

有没有办法让我在第一次重定向后停止其他验证

在views.py

from django.contrib import messages
# from django.core.exceptions import ValidationError
from django.shortcuts import render, redirect

def register(request):
    if request.method == 'POST':
        form = request.POST
        phone_number = validate_phone(request, form.get("phone_number"))
        username = validate_user_name(request, form.get("username"))
        password = validate_password(request, password1=form.get("password1"),password2=form.get("password2"))
        ....other_fields....
    return render(request, 'registration.html',)



def validate_user_name(request, username):
    username = username.strip()
    new = MyUser.objects.filter(username=username)
    if new.count():
        messages.error(request, "User with that Username Already Exist")
        return redirect("pre_register")
        # raise ValidationError("User with that Username Already Exist", code="username_error")
    return username

def validate_password(request, password1, password2):
    if password1 and password2 and password1 != password2:
        messages.error(request, "Passwords don't match")
        return redirect("pre_register")
        # raise ValidationError("Password don't match")
    return password2

    ....other_validations....

在registration.html中:

<h3 class="register-heading">Apply as a Member</h3>
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message.tags }} : {{message}}</li>
{% endfor %}
<form method="post">
    <input type="text" class="form-control" placeholder="Username *" value=""
                                               required="required" name="username"/>
    <input type="text" minlength="10" maxlength="10" name="phone_number"
                                               class="form-control"
                                               placeholder="Your Phone *" value="" required="required"/>
    <input type="password" class="form-control" placeholder="Password *" value=""
                                               required="required" , name="password1"/>
    <input type="password" class="form-control" placeholder="Confirm Password *"
                                               value="" required="required" , name="password2"/>

</form>

假设用户输入了一个已经存在的用户名,我想要的是:

  1. 保留已经输入的post数据
  2. 一旦点击这条线
messages.error(request, "User with that Username Already Exist")
        return redirect("pre_register")

, 我只想要这个作为结果(在模板中)

error: User with that Email ALready Exists

相反,我一次收到所有错误消息

error: User with that Email ALready Exists
error: Passwords don't match
...all the other errors....

我知道这是因为从技术上讲,这是我应该得到的,但我如何实现上面我想要的。 我认为这样做的一种方法是在我设置错误消息之前清除所有消息,但这意味着给服务器更多的工作要做,因为它仍然会在只留下最后一个之前检查所有这些消息(事实上我什至不知道该怎么做 )

如有任何帮助,我们将不胜感激

首先,我认为您混淆了何时使用渲染以及何时使用重定向。通常的模式是在表单验证时使用 redirect,这样用户就不会意外地重新提交数据,而在数据无效时使用 render,以便呈现错误。你在做相反的事情。有关详细信息,请参阅 this antipattern

其次,问题是您的验证函数 return 是一个 HTTP 响应。用户永远不会在您的验证函数中被重定向。您需要 return 来自视图函数的 HTTP 响应才能使用户重定向。您可能会使用注释方法来提高 ValidationErrors 然后在视图中捕获它们。如果发生错误,您添加一条消息并呈现模板。

类似于:

def register(request):
    if request.method == 'POST':
        form = request.POST
        try:
            phone_number = validate_phone(request, form.get("phone_number"))
            username = validate_user_name(request, form.get("username"))
            password = validate_password(request, password1=form.get("password1"),password2=form.get("password2"))
            ....other_fields....
            
            # If all validations pass, you redirect
            return redirect('pre_register')
        except ValidationError as e:
            messages.error(request, str(e))
            # passes down to render

    # This gets called when it's GET request or the form validation failed.
    return render(request, 'registration.html',)