【问题标题】:Django Model Form not saving to databaseDjango 模型表单未保存到数据库
【发布时间】:2021-06-28 00:35:31
【问题描述】:

我有以下 ModelForm,当我按如下方式使用时,它不会保存到数据库中。我在这里尝试过其他帖子和答案,但无法保存。

如果我使用相同的类基础视图 (CreateView) 并在 HTML 中使用 {{form}} 的输入,我可以让它工作并将其保存到数据库中,但我需要单独添加表单字段下面是为我创建的带有单独输入的 HTML 页面。

帖子的输出可以在终端打印,但如前所述,不会打印到数据库。

希望这一切都有意义,并在此先感谢我能得到的任何帮助。

models.py

class ASPBookings(models.Model):

program_types = (
    ('Athlete Speaker & Expert Program', 'Athlete Speaker & Expert Program'),
    ('Be Fit. Be Well', 'Be Fit. Be Well')
)

presentation_form_options = (
    ('Face to Face', 'Face to Face'),
    ('Virtual', 'Virtual'),
)
organisation_types = (
    ('Goverment School', 'Goverment School'),
    ('Community Organisation', 'Community Organisation'),
    ('Non-Goverment School', 'Non-Goverment School'),
    ('Other', 'Other')
)

contact_name = models.CharField(max_length=80)
program_type = models.CharField(max_length=120,choices=program_types)
booking_date = models.DateField()
booking_time = models.DateTimeField(default=datetime.now())
duration = models.CharField(max_length=10, default="1")
email = models.EmailField()
phone_number = models.CharField(max_length=120)
speaker_brief = models.TextField()
presentation_form = models.CharField(max_length=120, choices=presentation_form_options)
audience_number = models.CharField(max_length=10)
street = models.CharField(max_length=120)
suburb = models.CharField(max_length=120)
region = models.CharField(max_length=50, default="1")
post_code = models.CharField(max_length=40)
organisation_type = models.CharField(max_length=120,choices=organisation_types)
athlete = models.ForeignKey(Athlete, default="13", on_delete=models.CASCADE)

def __str__(self):
    return self.contact_name

forms.py

class ASPBookingsForm(forms.ModelForm):

class Meta():
    model = ASPBookings
    fields = ('__all__')    

views.py

class ASPBookingsCreateView(CreateView):
form_class = ASPBookingsForm
model = ASPBookings
template_name = "vistours/bookings_asp.html"

def post(self, request):
    if request.method == 'POST':
        form = self.form_class(request.POST)
        print(request.POST)
        if form.is_valid():
            program_type = form.cleaned_data['prev_program']
            booking_date = form.cleaned_data['prev_date']
            booking_time = form.cleaned_data['prev_time']
            duration = form.cleaned_data['prev_duration']
            street = form.cleaned_data['street']
            suburb = form.cleaned_data['suburb']
            post_code = form.cleaned_data['postcode']
            region = form.cleaned_data['region']
            organisation_type = form.cleaned_data['org_type']
            audience_number = form.cleaned_data['audience']
            presentation_form = form.cleaned_data['presentation_form']
            contact_name = form.cleaned_data['contact_name']
            email = form.cleaned_data['email']
            phone_number = form.cleaned_data['phone']
            speaker_brief = form.cleaned_data['comments']
            athlete = form.cleaned_data['athlete']
            form.save()
        return render(request, self.template_name)

HTML

        <!DOCTYPE html>
{% load static %}
<html lang="en">
<head>

  <meta charset="utf-8">

  <title>Athlete Speaker Program</title>



  <!-- VIS Branding -->
  <link rel="stylesheet" type="text/css" href="{% static 'vistours/css/vis.css' %}">
  <link rel="stylesheet" type="text/css" href="{% static 'vistours/css/number-input.css' %}">


  <!-- JQuery -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>


  <!-- Bootstrap -->
  <link href="{% static 'vistours/css/bootstrap.min.css' %}" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.min.js" integrity="sha384-nsg8ua9HAw1y0W1btsyWgBklPnCUAFLuTMS2G72MMONqmOymq585AcH49TLBQObG" crossorigin="anonymous"></script>


</head>
<body>


  <form method="post" class="needs-validation" novalidate enctype="multipart/form-data">
    {% csrf_token %}
    <div class="container-fluid pt-3">
      <!-- Nav Bar -->
      <div class="row">
        <div class="col-md-2"></div>
        <div class="col-md-8"><img alt="VIS Logo" src="https://www.vis.org.au/theme/vis/img/logo.svg" style="height: 50px;" class="img-fluid"></div>
        <div class="col-md-2"></div>
      </div>
      <!-- END Nav Bar -->
      <div id="duration_container" class="row py-5">
        <div class="col-md-2">
        </div>
        <div class="col-md-8">
          <div class="card">
            <h5 class="card-header">Address & Organisation Type</h5>
            <div class="card-body">
              <h5 class="card-title">Please fill out the address fields</h5>
              <p class="card-text">Uncheck the box below if you've already booked a session with us in an earlier date.</p>

              <div class="form-floating mb-3">
                <input type="text" required class="form-control" id="street" name="street" placeholder="Flinders Street" value={{street}} >
                <label for="street">Street</label>
                <div class="invalid-feedback">
                  Please enter a valid street name
                </div>
              </div>

              <div class="form-floating mb-3">
                <input type="text" required class="form-control" id="suburb" name="suburb" placeholder="Albert Park" value={{suburb}}>
                <label for="suburb">Suburb</label>
                <div class="invalid-feedback">
                  Please enter a valid suburb name
                </div>
              </div>
              <div class="form-floating mb-3">
                <input required oninput="this.value =
                !!this.value && Math.abs(this.value) >= 0 ? Math.abs(this.value) : null; if(this.value<0){this.value= this.value =0} else if(this.value>9999){this.value= this.value =9999}
                " type="number" min="0" max="9999" class="form-control" id="postcode" name="postcode" placeholder="3000" value={{post_code}}>
                <label for="postcode">Post Code</label>
                <div class="invalid-feedback">
                  Please enter a valid post code
                </div>
              </div>
              <div class="form-floating mb-3">
                <select class="form-select" id="region" name="region" aria-label="Region" value={{region}}>
                  <option value="1">Metro</option>
                  <option value="2" selected>Suburb</option>
                </select>
                <label for="region">Region</label>
              </div>
              <div class="form-floating mb-3">
                <select class="form-select" id="org_type" name="org_type" aria-label="Organisation Type" value={{form.organisation_type}}>
                  <option value="1">Community organisation</option>
                  <option value="2">Corporation</option>
                  <option value="3" selected>Government school</option>
                  <option value="4">Non-Government school</option>
                  <option value="5">Other</option>
                </select>
                <label for="org_type">Organisation Type</label>
              </div>


            </div>
          </div>
        </div>
        <div class="col-md-2">

        </div>

      </div>
      <!-- Next Button DIV -->
      <div class="row">
        <div class="col-2">
        </div>
        <div class="col-8">
          <a href="#time_container" id="time_button" class="btn btn-primary">Next</a>
        </div>
        <div class="col-2"></div>
      </div>
      <!-- END Next Button DIV -->

      <div class="col-xs-12" style="height:350px;"></div>


      <!--Time Container Blank Space-->
      <div id="time_container" class="row py-5">
        <div class="col-md-2"></div>
        <div class="col-md-8">
        </div>
        <div class="col-md-2"></div>
      </div>
      <!--END Time Container Blank Space-->

      <!-- Time Slots -->
      <div class="row pb-5">
        <div class="col-md-2">
        </div>
        <div class="col-md-8">
          <div class="card">
            <h5 class="card-header">Audience</h5>
            <div class="card-body">
              <h5 class="card-title">Audience Number</h5>
              <p class="card-text">How many people will be attending this conference</p>

              <div class="form-floating mb-3">
                <input required oninput="this.value =
                !!this.value && Math.abs(this.value) >= 0 ? Math.abs(this.value) : null;if(this.value<0){this.value= this.value =0} else if(this.value>9999){this.value= this.value =9999}
                " type="number" min="0" max="9999" class="form-control" id="audience" name="audience" placeholder="0 - 9999" value={{audience_number}}>
                <label for="audience">Audience Number</label>
                <div class="invalid-feedback">
                  Please enter a valid audience number
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="col-md-2">
        </div>
      </div>

      <!-- Next Button DIV -->
      <div class="row">
        <div class="col-2">
        </div>
        <div class="col-8">
          <a href="#date_container" id="date_button" class="btn btn-primary">Next</a>
        </div>
        <div class="col-2"></div>
      </div>
      <!-- END Next Button DIV -->

      <div class="col-xs-12" style="height:350px;"></div>
      <!--END Time Slots-->

      <!--Date Container Blank Space-->
      <div id="date_container" class="row py-5">
        <div class="col-md-2"></div>
        <div class="col-md-8">
        </div>
        <div class="col-md-2"></div>
      </div>
      <!--END Date Container Blank Space-->

      <div class="row pb-5">
        <div class="col-md-2">
        </div>
        <div class="col-md-8">
          <div class="card">
            <h5 class="card-header">Contact Information</h5>
            <div class="card-body">
              <h5 class="card-title">Contact info and speaker brief</h5>
              <p class="card-text">
                Please fill out the contact form and explain what function/class the speaker will be presenting to, what topics you would like the speaker to cover and if you have any requests for type of speaker (male/female/sport/para athlete, etc.) under <em>Speaker Brief</em> section.</p>
                <div class="form-floating mb-3">
                  <select class="form-select" id="presentation_form" name="presentation_form" aria-label="Presentation Form" value={{presentation_form}}>
                    <option value="1" selected>Face-to-Face</option>
                    <option value="2">Virtual</option>

                  </select>
                  <label for="presentation_form">Preferred Presentation Form</label>
                </div>
                <div class="form-floating mb-3">
                  <input required type="text" class="form-control" id="contact_name" name="contact_name" placeholder="John Doe" value={{contact_name}}>
                  <label for="contact_name">Contact Name</label>
                  <div class="invalid-feedback">
                    Please enter a valid contact name
                  </div>
                </div>
                <div class="form-floating mb-3">
                  <input required type="text" class="form-control" id="athlete" name="athlete" placeholder="Athlete Name" value={{athlete}}>
                  <label for="contact_name">Athlete Name</label>
                  <div class="invalid-feedback">
                    Please enter a valid contact name
                  </div>
                </div>
                <div class="form-floating mb-3">
                  <input required type="email" class="form-control" id="email" name="email" placeholder="name@example.com" value={{email}}>
                  <label for="email">Email</label>
                  <div class="invalid-feedback">
                    Please enter a valid email address
                  </div>
                </div>
                <div class="form-floating mb-3">
                  <input required pattern="^((\+61\s?)?(\((0|02|03|04|07|08)\))?)?\s?\d{1,4}\s?\d{1,4}\s?\d{0,4}$"  type="text" class="form-control" id="phone" name="phone" placeholder="0400 000 000" value={{phone_number}}>
                  <label for="phone">Phone</label>
                  <div class="invalid-feedback">
                    Please enter a valid phone number
                  </div>
                </div>
                <div class="form-floating">
                  <textarea required class="form-control" placeholder="Leave a comment here" id="comments" name="comments" maxlength="500" value={{speaker_brief}}></textarea>
                  <label for="comments">Speaker Brief (Max 500 Characters)</label>
                  <div class="invalid-feedback">
                    Please explain the topics you want the speaker to present
                  </div>
                </div>





              </div>

            </div>
          </div>
          <div class="col-md-2">
          </div>
        </div>
        <!-- Form Validation Alert Box -->
        <div class="row py-3" id="alert_box" style="visibility: hidden;">
          <div class="col-2">
          </div>
          <div class="col-8">
            <div class="alert alert-danger alert-dismissible fade show" role="alert">
              <strong>Oops!</strong> Some of the fields above need to be reviewed.
              <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
          </div>
          <div class="col-2">
          </div>
        </div>
        <!-- END Form Validation Alert Box -->
        <!-- Submit Button DIV -->
        <div class="row">
          <div class="col-2">
          </div>
          <div class="col-8 d-flex flex-row-reverse">
            <input type="submit" name="submit" class="btn btn-primary" value="Submit">

          </div>
          <div class="col-2">

          </div>
        </div>
        <!-- END Submit Button DIV -->
        <div class="col-xs-12" style="height:200px;"></div>

      </div>
      <!-- hidden inputs -->
      <div style="display: none; visibility: hidden;">
        <input type="text" name="prev_time" id="prev_time">
        <input type="text" name="prev_date" id="prev_date">
        <input type="text" name="prev_duration" id="prev_duration">
        <input type="text" name="prev_program" id="prev_program">
      </div>
    </form>
    <script src="{% static 'vistours/js/form-validation.js' %}"></script>


    <script>


      document.getElementById("prev_time").value = sessionStorage.getItem('time');
      document.getElementById("prev_date").value = sessionStorage.getItem('date');
      document.getElementById("prev_duration").value = sessionStorage.getItem('duration');
      document.getElementById("prev_program").value = sessionStorage.getItem('program');

    </script>
  </body>






  </html>

【问题讨论】:

    标签: django django-models django-views django-forms django-templates


    【解决方案1】:

    我认为您的表单可能无效。尝试在 if form.is_valid() 语句对应的 else 语句中打印 form.errors。

    另一个建议是使用 Django 表单生成 html,而不是自己生成所有内容(这容易出错且难以管理)。您仍然可以将表单域分开。查看以下网址:

    https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html#accessing-the-form-fields-individually

    【讨论】:

    • 感谢 Ajeet,当我将表单链接到 HTML 输入时,是否应该将表单字段名称添加到输入值中。例如。
    • 就像我在 else 语句中打印表单错误后不断收到回复一样,说“此字段是必需的”,就好像没有输入数据一样。
    • 您不需要在 HTML 中编写输入语句。当您在 django 模板中执行 {{ form.suburb }} 时,Django 会将其转换为 HTML 本身。在您的情况下,它将相当于
    • 这适用于单个输入,例如{{form.suburb}} 。如果我们允许 Django 创建输入,我们是否也可以在输入中添加一个类以允许它与 Boostrap 集成?
    • 是的,您可以从模型窗体的小部件中添加类、占位符等。 docs.djangoproject.com/en/3.1/topics/forms/modelforms/… 要将类添加到文本字段,您应该将 'field': forms.TextInput(attrs={'class': 'your_class'}) 添加到小部件字典(请参阅上面的链接)
    猜你喜欢
    • 2020-07-11
    • 2021-08-13
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多