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

Django如何在delivery_date前7天禁用Booking的UpdateView与DeleteView功能

实现步骤如下

1. 给Booking模型增加可编辑状态判断方法

修改models.py中的Booking类,新增is_editable方法用于判断当前预约是否允许修改/删除:

class Booking(models.Model):
    # 原有字段保持不变
    customer_name = models.ForeignKey(Customer,on_delete=models.CASCADE,null=True)
    username = models.ForeignKey(User,on_delete=models.CASCADE)
    qty_plts = models.PositiveSmallIntegerField(default=1)
    cbm = models.PositiveSmallIntegerField(default=1)
    created_date = models.DateTimeField(default=timezone.now())
    delivery_date = models.DateField(null=True)
    delivery_time = models.TimeField(null=True)
    booking_number = models.CharField(max_length=50,unique=True)
    
    # 新增可编辑判断方法
    def is_editable(self):
        from django.utils import timezone
        if not self.delivery_date:
            return True
        days_until_delivery = (self.delivery_date - timezone.now().date()).days
        return days_until_delivery >= 7

    # 原有方法保持不变
    def __str__(self):
        return self.booking_number
    # 剩下的save、get_absolute_url方法不变

2. 前端模板隐藏不可编辑预约的操作按钮

修改booking_detail.html中的按钮区域,仅当预约可编辑时显示更新/删除按钮,否则展示提示:

<div class="container">
  {% if booking_detail.is_editable or user.is_staff %}
  <a class="btn btn-primary" href="{% url 'bookmyslot:update' pk=booking_detail.pk %}">Update Booking</a>
  <a class="btn btn-danger" href="{% url 'bookmyslot:delete' pk=booking_detail.pk %}">Delete Booking</a>
  {% else %}
  <p class="text-warning">距离配送日期不足7天,该预约已无法修改或删除</p>
  {% endif %}
</div>

注:如果不需要管理员豁免权限,直接删除or user.is_staff判断即可

3. 视图层增加权限校验(防止直接访问操作URL绕过前端限制)

首先修改views.py头部导入redirect:

from django.shortcuts import render, redirect

然后给BookingUpdate新增dispatch校验逻辑:

class BookingUpdate(LoginRequiredMixin,UpdateView):
    login_url = '/login'
    template_name = 'bookmyslot/booking_form_update.html'
    model = Booking
    form_class = BookingForm

    def get_form_kwargs(self, **kwargs):
        form_kwargs = super(BookingUpdate,self).get_form_kwargs(**kwargs)
        form_kwargs['username'] = self.request.user
        return form_kwargs
    
    # 新增校验逻辑
    def dispatch(self, request, *args, **kwargs):
        booking = self.get_object()
        # 不需要管理员豁免就删除`not request.user.is_staff`判断
        if not request.user.is_staff and not booking.is_editable():
            messages.error(request, "距离配送日期不足7天,无法修改该预约")
            return redirect('bookmyslot:detail', pk=booking.pk)
        return super().dispatch(request, *args, **kwargs)

给BookingDelete新增同样的dispatch校验逻辑:

class BookingDelete(LoginRequiredMixin,DeleteView):
    login_url = '/login'
    model = Booking
    success_url = reverse_lazy('bookmyslot:list')
    
    # 新增校验逻辑
    def dispatch(self, request, *args, **kwargs):
        booking = self.get_object()
        # 不需要管理员豁免就删除`not request.user.is_staff`判断
        if not request.user.is_staff and not booking.is_editable():
            messages.error(request, "距离配送日期不足7天,无法删除该预约")
            return redirect('bookmyslot:detail', pk=booking.pk)
        return super().dispatch(request, *args, **kwargs)

4. 表单层补充修改配送日期的校验(可选)

如果允许用户修改配送日期,需要在forms.py的clean方法中补充校验,避免用户把配送日期改到不足7天的范围:

def clean(self):
    cleaned_data = super(BookingForm,self).clean()
    cleaned_delivery_date = cleaned_data.get('delivery_date')
    cleaned_delivery_time = cleaned_data.get('delivery_time')

    # 新增修改配送日期的校验
    if self.instance.pk: # 仅更新操作需要校验
        days_until_new_delivery = (cleaned_delivery_date - timezone.now().date()).days
        if days_until_new_delivery <7:
            raise forms.ValidationError("新的配送日期距离当前不足7天,无法修改")

    # 原有冲突校验逻辑保持不变
    booking_number = f"{cleaned_delivery_date:%Y%m%d}{cleaned_delivery_time:%H%M}"
    if Booking.objects.filter(booking_number=booking_number).exists():
        # 原有冲突提示逻辑不变
        x = Booking.objects.filter(delivery_date=cleaned_delivery_date)
        occupied_slots = []
        for i in range(0,len(x)):
            occupied_slots.append(x[i].booking_number[-4:])
        all_slots = ['{:02d}00'.format(x) for x in range(7, 13)]
        available_slot = check_free_time(all_slots,occupied_slots)
        if available_slot:
            message = f"Requested slot is already booked, here are today's available times: {os.linesep.join(available_slot)}"
            raise forms.ValidationError(message)
        else:
            message = "There are no more slots available today, please choose another date"
            raise forms.ValidationError(message)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:09:00