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

如何在Django预订表单中移除数据库已存在的时间选项?

Django预订表单动态过滤已占用时间

要实现所选日期下仅显示未被预订的时间选项,可以通过「后端查询可用时间 + 前端AJAX动态更新」的方式实现,以下是具体步骤:

1. 完善表单类(若未定义)

确保你的BookingForm基于ModelForm创建,在forms.py中添加:

from django import forms
from .models import Booking, TIME_CHOICES

class BookingForm(forms.ModelForm):
    class Meta:
        model = Booking
        fields = ['first_name', 'last_name', 'email_address', 'phone_number', 'date_of_booking', 'time_of_booking', 'number_of_people', 'special_requests']

2. 添加AJAX接口视图

在views.py中新增视图,用于接收日期参数、查询可用时间并返回JSON结果:

from django.http import JsonResponse
from .models import Booking, TIME_CHOICES
import datetime

def get_available_times(request):
    selected_date = request.GET.get('date')
    if not selected_date:
        return JsonResponse({'available_times': []})
    
    # 转换日期格式并查询已预订时间
    booking_date = datetime.datetime.strptime(selected_date, '%Y-%m-%d').date()
    booked_times = Booking.objects.filter(date_of_booking=booking_date).values_list('time_of_booking', flat=True)
    # 筛选未被占用的时间选项
    available_times = [time for time in TIME_CHOICES if time[0] not in booked_times]
    formatted_times = [{'value': t[0], 'text': t[1]} for t in available_times]
    
    return JsonResponse({'available_times': formatted_times})

3. 配置路由

在urls.py中添加AJAX接口的路由:

from django.urls import path
from . import views

urlpatterns = [
    path('make-booking/', views.make_booking, name='make_booking'),
    path('get-available-times/', views.get_available_times, name='get_available_times'),
    # 其他已有路由...
]

4. 修改模板实现动态更新

在booking/make_booking.html中添加JavaScript,监听日期选择事件并更新时间下拉框:

<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">提交预订</button>
</form>

<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
$(document).ready(function() {
    // 页面加载时初始化可用时间
    updateTimeOptions($('#id_date_of_booking').val());

    // 监听日期选择变化
    $('#id_date_of_booking').on('change', function() {
        updateTimeOptions($(this).val());
    });

    // 更新时间选项的函数
    function updateTimeOptions(date) {
        $.ajax({
            url: "{% url 'get_available_times' %}",
            data: {'date': date},
            dataType: 'json',
            success: function(res) {
                const timeSelect = $('#id_time_of_booking');
                timeSelect.empty();
                res.available_times.forEach(time => {
                    timeSelect.append($('<option>').val(time.value).text(time.text));
                });
            }
        });
    }
});
</script>

可选:静态初始化过滤(非动态)

如果不需要实时更新,可在页面加载时直接根据默认日期过滤时间选项,修改make_booking视图:

def make_booking(request):
    if request.method == 'POST':
        form = BookingForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect(get_bookings)
    else:
        target_date = request.GET.get('date')
        form = BookingForm()
        if target_date:
            try:
                booking_date = datetime.datetime.strptime(target_date, '%Y-%m-%d').date()
                booked_times = Booking.objects.filter(date_of_booking=booking_date).values_list('time_of_booking', flat=True)
                available_times = [t for t in TIME_CHOICES if t[0] not in booked_times]
                form.fields['time_of_booking'].choices = available_times
            except ValueError:
                pass
    
    context = {'form': form}
    return render(request, 'booking/make_booking.html', context)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:25:20