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
相关产品推荐
相关产品推荐

