Django美甲沙龙预约网站问题:已预约时段无法移除
问题:Django美甲沙龙预约平台无法移除已预约时段
场景说明
我正在用Django开发首个网站,给女友的美甲沙龙做预约平台。通过FreeHoursModel、Customer两个模型及一对一关系实现了预约表单与空闲时段选择功能,但目前无法移除已被预约的时段。
模型代码
class FreeHoursModel(models.Model): EARLY = '10:00' MID = '13:00' LATE = '16:00' HOURS = [(x, x) for x in (EARLY, MID, LATE)] time = models.CharField( max_length=20, choices=HOURS, default=1, ) date = models.DateField( ) def __str__(self): return f"{str(self.date)} - {self.time}" class Customer(models.Model): MAX_LENGTH = 25 name = models.CharField( max_length=MAX_LENGTH, ) last_name = models.CharField( max_length=MAX_LENGTH, ) phone_number = models.IntegerField() date_of_booking = models.DateField( auto_now_add=True ) hours = models.OneToOneField( FreeHoursModel, on_delete=models.DO_NOTHING ) class Meta: get_latest_by = 'date_of_booking'
当前视图代码
class IndexView(generic.TemplateView): template_name = 'landing_page/landing_page.html' class BookingView(generic.CreateView): template_name = 'booking_page/booking.html' success_url = reverse_lazy('summary') form_class = CustomerForm def form_valid(self, form): name = form.cleaned_data['name'] last_name = form.cleaned_data['last_name'] phone_number = form.cleaned_data['phone_number'] hour = str(form.cleaned_data['hours']) # print(hour.encode("utf-8")) return super(BookingView, self).form_valid(form) def get_success_url(self): if self.success_url: return self.success_url return super().get_success_url() def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['customer'] = CustomerForm() return context class SummaryView(generic.TemplateView): template_name = 'booking_page/summary.html' # if Customer.objects.all(): # latest_created_booking = Customer.objects.latest() # latest_taken_hour_id = latest_created_booking.hours_id # latest_taken_hour = FreeHoursModel.objects.filter(id=latest_taken_hour_id)[0] # print(latest_taken_hour) # latest_taken_hour.delete() def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) return context
尝试的方案及问题
我尝试在预约成功跳转的SummaryView中删除与最新创建的Customer实例关联的FreeHoursModel记录,写了上述注释中的代码,但这段代码仅在项目启动时执行一次,访问SummaryView时完全不生效。
解决建议
1. 最优方案:在预约成功时立即删除时段
把删除逻辑移到BookingView的form_valid方法中——这是最合理的时机,用户提交预约表单并成功创建Customer实例后,立刻删除对应的空闲时段:
class BookingView(generic.CreateView): template_name = 'booking_page/booking.html' success_url = reverse_lazy('summary') form_class = CustomerForm def form_valid(self, form): # 先调用父类方法保存Customer实例 response = super().form_valid(form) # 获取刚创建的Customer对象 customer = self.object # 删除关联的空闲时段记录 customer.hours.delete() return response
这种方式逻辑顺畅,不会出现页面重复执行删除的问题。
2. 备选:若必须在SummaryView处理
如果坚持要在SummaryView中执行删除,必须把代码放到视图的方法内部(比如get_context_data),而不是类的顶层(类顶层代码只会在项目启动加载类时执行一次):
class SummaryView(generic.TemplateView): template_name = 'booking_page/summary.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 执行删除逻辑,添加异常处理避免无预约记录时报错 try: latest_booking = Customer.objects.latest() latest_booking.hours.delete() except Customer.DoesNotExist: pass return context
注意:这种方式存在缺陷——用户刷新SummaryView页面时会重复执行删除操作,可能引发错误,因此不推荐。
3. 额外优化点
- 把
Customer模型中的phone_number字段改为CharField,因为IntegerField无法存储带区号、前导零的手机号,且手机号长度可能超出整数范围。 - 可以考虑给
FreeHoursModel添加is_booked布尔字段替代直接删除记录,这样后续取消预约、恢复时段更灵活,也方便查看历史预约数据。
内容的提问来源于stack exchange,提问作者Nikolai Nikolov
相关产品推荐
相关产品推荐

