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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 06:30:08