У меня есть следующая форма с несколькими логическими полями:
class RegistrationForm(UserCreationForm):
guardianSource = forms.BooleanField(widget=forms.CheckboxInput(attrs={'id':'guardianSource'}),required=False)
bbcSource = forms.BooleanField(required=False)
independentSource = forms.BooleanField(required=False)
categoryCoronaVirus = forms.BooleanField(required=False)
categoryPolitics = forms.BooleanField(required=False)
categorySport = forms.BooleanField(required=False)
#Telling the registration form what kind of data we are going to be modelling/ what the form needs to look like
class Meta:
model = Account
fields = ("username", "password1", "password2", "guardianSource", "bbcSource", "independentSource", "categoryCoronaVirus", "categoryPolitics", "categorySport")
Шаблон регистра выглядит следующим образом:
<form class="form-signin" method="POST">{% csrf_token %}
<h1 class="h3 mb-3 font-weight-normal">Register</h1>
<label for="username" class="sr-only">Username</label>
<input type="text" name="username" id="username" class="form-control" placeholder="User name" required autofocus>
<label for="inputPassword1" class="sr-only">Password</label>
<input type="password" name="password1" id="inputPassword1" class="form-control" placeholder="Password" required>
<label for="inputPassword2" class="sr-only">Password</label>
<input type="password" name="password2" id="inputPassword2" class="form-control" placeholder="Confirm Password" required>
<br>
<div class="form-control">
<p><b>Please choose news sources!</b></p>
<label for="guardianSource" >The Guardian</label>
<input type="checkbox" name="source" id="guardianSource">
<br>
<label for="bbcSource" >BBC News</label>
<input type="checkbox" name="source" id="bbcSource">
<br>
<label for="independentSource" >The Independent</label>
<input type="checkbox" name="source" id="independentSource">
</div>
<br>
<div class="form-control">
<p><b>Please choose news category!</b></p>
<label for="categoryCoronaVirus" >Corona Virus</label>
<input type="checkbox" name="category" id="categoryCoronaVirus">
<br>
<label for="categoryPolitics" >Politics</label>
<input type="checkbox" name="category" id="categoryPolitics">
<br>
<label for="categorySport" >Sport</label>
<input type="checkbox" name="category" id="categorySport">
</div>
{% for field in registration_form %}
<p>
{% for error in field.errors %}
<p class="alert alert-danger card-header text-center flashit"> {{ error }}</p>
{% endfor %}
</p>
{% endfor %}
{% if registration_form.non_field_errors %}
<div style="color:red;">
<p>{{registration_form.non_field_errors}}</p>
</div>
{% endif %}
<h6 class="text-muted">
NOTE: You <b>MUST</b> select at least 1 choice for each!!!
</h6>
<div id="error_message"> </div>
<button class="btn btn-lg btn-primary btn-block" type="submit" onclick="valthisform()">Register</button>
</form>
Существует функция JavaScript, которая проверяет, хотя бы 1 флажок для категории и 1 для источника установлен перед отправкой формы:
function valthisform(){
var guardianSource = document.getElementById("guardianSource").checked;
var bbcSource = document.getElementById("bbcSource").checked;
var independentSource = document.getElementById("independentSource").checked;
var checkedSource = false;
var categoryCoronaVirus = document.getElementById("categoryCoronaVirus").checked;
var categoryPolitics = document.getElementById("categoryPolitics").checked;
var categorySport = document.getElementById("categorySport").checked;
var checkedCategory = false;
if(guardianSource ===true || bbcSource===true || independentSource===true){
checkedSource = true;
}
if(categoryCoronaVirus===true || categoryPolitics===true || categorySport===true){
checkedCategory = true;
}
if(checkedSource ===false && checkedCategory===false){
document.getElementById('error_message').innerHTML = '<div class="alert alert-danger card-header text-center flashit"><strong>Warning!</strong> No source and category selected!</div>';
event.preventDefault();
}
else if(checkedSource ===false ){
document.getElementById('error_message').innerHTML = '<div class="alert alert-danger card-header text-center flashit"><strong>Warning!</strong> No source selected!</div>';
event.preventDefault();
}
else if(checkedCategory===false){
document.getElementById('error_message').innerHTML = '<div class="alert alert-danger card-header text-center flashit"><strong>Warning!</strong> No category selected!</div>';
event.preventDefault();
}
}
Проблема заключается в том, что когда я не отмечаю ни одного флажка при регистрации, функция JavaScript работает так, как это должно быть - он предотвращает сохранение данных в базе данных и печатает все, что должен. После печати предупреждающего сообщения я отмечаю несколько полей и отправляю форму. Форма отправляет и перенаправляет на домашнюю страницу, однако, когда я просматриваю базу данных, проверенные логические значения не сохраняются - все они ложные. Мой django вид для регистра:
def registration(request):
context = {}
if request.user.is_authenticated: # If user is logged in, redirect to home screen, they cannot register again!
return redirect('home')
if request.POST:
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
account = authenticate(username=username, password=raw_password)
login(request, account)
return redirect('home')
else:
context['registration_form'] = form
else: # GET request
form = RegistrationForm()
context['registration_form'] = form
return render(request, 'accounts/register.html', context)
РЕДАКТИРОВАТЬ: я наконец-то нашел ошибку после прохождения коммитов на git и сравнения файлов с самыми ранними коммитами. В основном код из регистрационного шаблона:
<label for="guardianSource" >The Guardian</label>
<input type="checkbox" name="source" id="guardianSource">
<br>
<label for="bbcSource" >BBC News</label>
<input type="checkbox" name="source" id="bbcSource">
<br>
<label for="independentSource" >The Independent</label>
<input type="checkbox" name="source" id="independentSource">
</div>
<br>
<div class="form-control">
<p><b>Please choose news category!</b></p>
<label for="categoryCoronaVirus" >Corona Virus</label>
<input type="checkbox" name="category" id="categoryCoronaVirus">
<br>
<label for="categoryPolitics" >Politics</label>
<input type="checkbox" name="category" id="categoryPolitics">
<br>
<label for="categorySport" >Sport</label>
<input type="checkbox" name="category" id="categorySport">
</div>
Я почему-то переименовал атрибут имени каждого флажка. После изменения значений на:
<label for="guardianSource" >The Guardian</label>
<input type="checkbox" name="guardianSource" id="guardianSource">
<br>
<label for="bbcSource" >BBC News</label>
<input type="checkbox" name="bbcSource" id="bbcSource">
<br>
<label for="independentSource" >The Independent</label>
<input type="checkbox" name="independentSource" id="independentSource">
</div>
<br>
<div class="form-control">
<p><b>Please choose news category!</b></p>
<label for="categoryCoronaVirus" >Corona Virus</label>
<input type="checkbox" name="categoryCoronaVirus" id="categoryCoronaVirus">
<br>
<label for="categoryPolitics" >Politics</label>
<input type="checkbox" name="categoryPolitics" id="categoryPolitics">
<br>
<label for="categorySport" >Sport</label>
<input type="checkbox" name="categorySport" id="categorySport">
</div>
Работает.