Django не сохраняет значения BooleanFields - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть следующая форма с несколькими логическими полями:

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>

Работает.

1 Ответ

0 голосов
/ 15 апреля 2020

Вы, кажется, повторяете некоторые поля модели в вашей форме снова. Это не обязательно и может вызвать эту ошибку. Если вы используете следующее в models.py и forms.py, то вызов метода save () должен сохранить все поля в вашей базе данных.

models.py:

class Account(AbstractUser):
    guardianSource = models.BooleanField(blank=True, null=True)
    bbcSource = models.BooleanField(blank=True, null=True)
    independentSource = models.BooleanField(blank=True, null=True)

    categoryCoronaVirus = models.BooleanField(blank=True, null=True)
    categoryPolitics = models.BooleanField(blank=True, null=True)
    categorySport = models.BooleanField(blank=True, null=True)

формы. py:

class RegistrationForm(UserCreationForm):

    class Meta:
        model = Account
        fields = ("username", "password1", "password2", "guardianSource", "bbcSource", "independentSource", "categoryCoronaVirus", "categoryPolitics", "categorySport")
        widget = {'guardianSource': forms.CheckboxInput(attrs={'id':'guardianSource'})}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...