Есть ли способ остановить другие проверки после первого перенаправления
в представлениях.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>
Скажем, пользователь вводит имя пользователя, которое уже существует, я хочу:
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
, когда данные недействительны, чтобы отображались ошибки. Вы делаете наоборот. Дополнительные сведения см. в статье этот антипаттерн.
Во-вторых, проблема в том, что ваша функция проверки возвращает HTTP-ответ. Пользователь никогда не перенаправляется в ваши функции проверки. Вам нужно вернуть ответ 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',)
Спасибо за быстрый ответ, я должен был просто использовать прокомментированный подход