有没有办法在重定向甚至清除消息后控制消息?
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>
假设用户输入了一个已经存在的用户名,我想要的是:
- 保留已经输入的post数据
- 一旦点击这条线
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',)
有没有办法让我在第一次重定向后停止其他验证
在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>
假设用户输入了一个已经存在的用户名,我想要的是:
- 保留已经输入的post数据
- 一旦点击这条线
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',)