You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django预约系统无法提交数据至数据库的问题求助

Django预约系统数据提交失败排查与修复

我正在开发一个Django预约系统,目前无法将数据提交至数据库。打开页面时会直接触发views.py中的messages.warning提示“ERROR!”,无其他报错信息。已定义Randevu模型,其中policlinic和doctor为ForeignKey字段,在HTML中是下拉选择框,但不确定该字段的处理是否正确。

相关代码

models.py

class Randevu(models.Model):
    STATUS = (
        ('New', 'Yeni'),
        ('True', 'Evet'),
        ('False', 'Hayır'),
    )
    policlinic=models.ForeignKey(Policlinic,on_delete=models.CASCADE)
    user=models.ForeignKey(User,on_delete=models.CASCADE)
    doctor=models.ForeignKey(Doctors,on_delete=models.CASCADE)
    phone = models.CharField(max_length=15)
    email = models.CharField(max_length=50)
    date=models.DateField(null=True)
    time=models.TimeField(null=True)
    payment= models.CharField(max_length=50)
    insurance= models.CharField(max_length=50)
    note=models.TextField(max_length=200)
    status = models.CharField(max_length=10, choices=STATUS,default='New')
    ip=models.CharField(max_length=20,blank=True)
    create_at = models.DateTimeField(auto_now_add=True)
    update_at = models.DateTimeField(auto_now=True)
    def str(self):
        return self.user.username

class AppointmentForm(ModelForm):
    class Meta:
        model=Randevu
        fields=['phone','email','date','time','payment','insurance','note'] 

views.py

def randevu(request):
    setting=Setting.objects.get(pk=1)
    policlinic=Policlinic.objects.all()
    doctor=Doctors.objects.all()
    context={'setting':setting ,'doctor':doctor,'policlinic':policlinic}
    if request.method=='POST':
        form=AppointmentForm(request.POST)
        if form.is_valid():
            current_user=request.user
            data=Randevu()
            data.user_id=current_user.id
            data.phone=form.cleaned_data['phone']
            data.email=form.cleaned_data['email']
            data.date=form.cleaned_data['date']
            data.time=form.cleaned_data['time']
            data.payment=form.cleaned_data['payment']
            data.insurance=form.cleaned_data['insurance']
            data.note=form.cleaned_data['note']
            data.ip=request.META.get('REMOTE_ADDR')
            data.save()
            messages.success(request,"DONE! :)")
            return render(request,'randevu.html',context)
    messages.warning(request,"ERROR!")
    return render(request,'randevu.html',context) 

urls.py

urlpatterns = [
 path('randevu',views.randevu,name='randevu') ]

randevu.html

<!-- MAKE AN APPOINTMENT -->
  
<section id="appointment" data-stellar-background-ratio="3">
  <div class="container">
       <div class="row">
            
            <div class="col-md-6 col-sm-6">
                 <img src="{% static 'images/appointment-image.jpg' %}" class="img-responsive" alt="">
            </div>

            <div class="col-md-6 col-sm-6">
                 <!-- CONTACT FORM HERE -->
                  <form id="appointment-form" role="form" action="{% url 'randevu' %}" method="post">
                      <!-- SECTION TITLE -->
                      <div class="section-title wow fadeInUp" data-wow-delay="0.4s">
                           <h2>Randevu Alın</h2>
                            {%if messages%}
                                 {%for message in messages%}
                                      <div class="alert alert-{{message.tags}}"role="alert">
                                           {{message}}
                                      </div>
                                 {%endfor%}
                            {%endif%}
                      </div>
                  
                      {% csrf_token %}
                      <div class="wow fadeInUp" data-wow-delay="0.8s">
                          <div class="col-md-6 col-sm-6">
                              <label for="email">E-mail</label>
                              <input type="email" class="form-control" id="email" name="email" placeholder="Your Email">
                         </div>

                           <div class="col-md-6 col-sm-6">
                              <label for="telephone">Telefon Numaranız</label>
                              <input type="tel" class="form-control" id="phone" name="phone" placeholder="Phone">
                           </div>

                          
                           <div class="col-md-6 col-sm-6">
                                <label for="date">Tarih</label>
                                <input type="date" name="date" id="date" value="" class="form-control">
                           </div>

                           <div class="col-md-6 col-sm-6">
                              <label for="time">Zaman</label>
                              <input type="time" name="time" id="time" value="" class="form-control">
                         </div>
                            
                           <div class="col-md-6 col-sm-6">
                                
                                <label for="select">Poliklinik Seçiniz</label>
                                
                                <select name="policlinic" class="form-control" id="policlinic">
                                 {% for rs in policlinic %}
                                     <option>{{rs.title}}</option>
                                 {%endfor%}
                                </select>  
                                  
                           </div>

                           <div class="col-md-6 col-sm-6">
                              <label for="select">Doktor Seçiniz</label>
                              <select name="doctor" class="form-control" id="doctor">
                                 {% for rs in doctor %}
                                   <option>{{rs.name}}</option>
                                 {%endfor%}
                              </select>
                         </div>

                         <div class="col-md-6 col-sm-6">
                          <label for="select">Ödeme Yöntemi</label>
                          <select name="payment" class="form-control" id="payment">
                               <option>Nakit</option>
                               <option>Banka Kartı</option>
                               <option>Kredi Kartı</option>
                               <option>Diğer</option>
                          </select>
                          </div>

                          <div class="col-md-6 col-sm-6">
                              <label for="select">Sigorta</label>
                              <select name="insurance" class="form-control" id="insurance">
                                   <option>SGK</option>
                                   <option>AXA Sağlık Sigortası</option>
                                   <option>Anadolu Sağlık Sigortası</option>
                                   <option>Allianz Sağlık Sigortası</option>
                                   <option>Akbank Sağlık Sigortası</option>
                                   <option>Tamamlayıcı Türkiye Sağlık Sigortası</option>
                                   <option>Diğer (Belirtiniz)</option>
                          </select>
                          </div>

                           <div class="col-md-12 col-sm-12">
                                
                                <label for="Message">Belirtmek istediğiniz herhangi bir durum</label>
                                <textarea class="form-control" rows="5" id="note" name="note" placeholder="Notunuz"></textarea>
                              {%if user.id is not None%}
                                <button type="submit" class="form-control" id="cf-submit" name="submit">Submit Button</button>
                              {%else%}
                                   Randevu oluşturmak için login olunuz!
                              {% endif %}
                           </div>
                      </div>
                </form>
            </div>
            
       </div>
  </div>
</section>

问题分析与修复方案

核心问题1:表单未包含必填外键字段

Randevu模型中的policlinic和doctor是必填外键,但AppointmentForm未包含这两个字段,前端提交的这两个字段值会被表单忽略,导致form.is_valid()验证失败,直接触发错误提示。

核心问题2:下拉选项未传递主键ID

前端下拉框的<option>仅显示名称,未设置value为对应模型的主键ID,即使表单包含字段,提交的文本值也无法关联数据库中的外键记录。

修复步骤

  1. 更新表单定义,添加外键字段
    修改models.py中的AppointmentForm:

    class AppointmentForm(ModelForm):
        class Meta:
            model=Randevu
            fields=['policlinic', 'doctor', 'phone','email','date','time','payment','insurance','note'] 
    
  2. 修复前端下拉框的value属性
    修改randevu.html中的科室和医生下拉框:

    <!-- 科室下拉框 -->
    <select name="policlinic" class="form-control" id="policlinic">
        {% for rs in policlinic %}
            <option value="{{ rs.id }}">{{ rs.title }}</option>
        {% endfor %}
    </select>
    
    <!-- 医生下拉框 -->
    <select name="doctor" class="form-control" id="doctor">
        {% for rs in doctor %}
            <option value="{{ rs.id }}">{{ rs.name }}</option>
        {% endfor %}
    </select>
    
  3. 优化视图逻辑,简化并增加调试信息
    修改views.py,利用ModelForm的save方法简化代码,同时添加表单错误打印:

    def randevu(request):
        setting=Setting.objects.get(pk=1)
        policlinic=Policlinic.objects.all()
        doctor=Doctors.objects.all()
        context={'setting':setting ,'doctor':doctor,'policlinic':policlinic}
        
        if request.method=='POST':
            form=AppointmentForm(request.POST)
            if form.is_valid():
                randevu = form.save(commit=False)
                randevu.user = request.user
                randevu.ip = request.META.get('REMOTE_ADDR')
                randevu.save()
                messages.success(request,"操作成功!:)")
                return redirect('randevu')  # 重定向避免重复提交
            else:
                # 打印表单错误到控制台,方便调试
                print(form.errors)
                messages.warning(request,"表单验证失败,请检查输入!")
        else:
            form = AppointmentForm()
        
        context['form'] = form
        return render(request,'randevu.html',context)
    
  4. 调试建议

    • 确保settings.py中DEBUG=True,开启调试模式查看详细错误
    • 查看控制台打印的form.errors,定位具体验证失败的字段

内容的提问来源于stack exchange,提问作者user18587924

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:35:19