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,即使表单包含字段,提交的文本值也无法关联数据库中的外键记录。
修复步骤
更新表单定义,添加外键字段
修改models.py中的AppointmentForm:class AppointmentForm(ModelForm): class Meta: model=Randevu fields=['policlinic', 'doctor', 'phone','email','date','time','payment','insurance','note']修复前端下拉框的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>优化视图逻辑,简化并增加调试信息
修改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)调试建议
- 确保settings.py中
DEBUG=True,开启调试模式查看详细错误 - 查看控制台打印的
form.errors,定位具体验证失败的字段
- 确保settings.py中
内容的提问来源于stack exchange,提问作者user18587924
相关产品推荐
相关产品推荐

