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

Django诊所管理系统:医生日程预约功能开发技术求助

Hey there! Let's work through implementing the doctor schedule and appointment booking feature for your Django clinic management system. I’ll break this down into actionable steps so you can get up and running quickly.

1. Refine Your Model Design

Instead of a simple Time model, we’ll create more robust models to track doctors, their available slots, and appointments. This structure gives you flexibility to manage availability and bookings clearly:

from django.db import models
from django.contrib.auth.models import User
from datetime import datetime

class Doctor(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    specialty = models.CharField(max_length=100)
    license_number = models.CharField(max_length=50, unique=True)

    def __str__(self):
        return f"{self.user.first_name} {self.user.last_name} - {self.specialty}"

class ScheduleSlot(models.Model):
    AVAILABILITY_CHOICES = (
        ('available', '空闲'),
        ('booked', '已占用'),
        ('unavailable', '不可预约'),  # For doctor leave/breaks
    )
    doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE, related_name='schedule_slots')
    date = models.DateField()
    start_time = models.TimeField()
    end_time = models.TimeField()
    status = models.CharField(max_length=20, choices=AVAILABILITY_CHOICES, default='available')

    def __str__(self):
        return f"{self.doctor.user.get_full_name()} - {self.date} | {self.start_time} to {self.end_time} ({self.status})"

class Appointment(models.Model):
    patient_name = models.CharField(max_length=100)
    patient_contact = models.CharField(max_length=20)
    patient_notes = models.TextField(blank=True)
    doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
    schedule_slot = models.OneToOneField(ScheduleSlot, on_delete=models.CASCADE, related_name='linked_appointment')
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"Appointment: {self.patient_name} with Dr. {self.doctor.user.last_name} on {self.schedule_slot.date}"
2. Generate Doctor Schedule Slots

Admins need an easy way to create recurring or one-time slots. Add a custom action in the Django admin to batch generate slots for a specific date:

from django.contrib import admin
from .models import Doctor, ScheduleSlot, Appointment
from datetime import time, timedelta

@admin.register(ScheduleSlot)
class ScheduleSlotAdmin(admin.ModelAdmin):
    list_display = ('doctor', 'date', 'start_time', 'end_time', 'status')
    list_filter = ('doctor', 'date', 'status')
    actions = ['generate_30min_slots']

    def generate_30min_slots(self, request, queryset):
        # Generate 30-minute slots from 9 AM to 5 PM for selected dates/doctors
        start_time = time(9, 0)
        end_time = time(17, 0)
        slot_duration = timedelta(minutes=30)

        for slot in queryset:
            current_time = start_time
            while current_time < end_time:
                next_time = (datetime.combine(datetime.today(), current_time) + slot_duration).time()
                ScheduleSlot.objects.get_or_create(
                    doctor=slot.doctor,
                    date=slot.date,
                    start_time=current_time,
                    end_time=next_time,
                    defaults={'status': 'available'}
                )
                current_time = next_time
        self.message_user(request, "Successfully generated 30-minute schedule slots!")
    generate_30min_slots.short_description = "Generate 30-minute slots for selected entries"

admin.site.register(Doctor)
admin.site.register(Appointment)
3. Implement Appointment Booking Logic

Create a view to handle booking, with validation to ensure slots are only booked if they’re available:

First, make an appointment form:

from django import forms
from .models import Appointment

class AppointmentForm(forms.ModelForm):
    class Meta:
        model = Appointment
        fields = ['patient_name', 'patient_contact', 'patient_notes']

Then the booking view (restricted to admins):

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import user_passes_test
from .models import ScheduleSlot, Appointment
from .forms import AppointmentForm

def is_admin(user):
    return user.is_staff

@user_passes_test(is_admin)
def book_appointment(request, slot_id):
    slot = get_object_or_404(ScheduleSlot, id=slot_id)
    
    if slot.status != 'available':
        return render(request, 'clinic/error.html', {'message': "This slot is already booked or unavailable!"})
    
    if request.method == 'POST':
        form = AppointmentForm(request.POST)
        if form.is_valid():
            appointment = form.save(commit=False)
            appointment.doctor = slot.doctor
            appointment.schedule_slot = slot
            appointment.save()
            # Mark the slot as booked
            slot.status = 'booked'
            slot.save()
            return redirect('appointment_success')
    else:
        form = AppointmentForm()
    
    return render(request, 'clinic/book_appointment.html', {
        'form': form,
        'slot': slot,
        'doctor': slot.doctor
    })
4. Display Doctor Schedule (Available/Booked Slots)

Create a view to show a doctor’s schedule for a selected date, splitting slots into available and booked groups:

from django.shortcuts import render, get_object_or_404
from .models import Doctor, ScheduleSlot
from datetime import date

def doctor_schedule(request, doctor_id):
    doctor = get_object_or_404(Doctor, id=doctor_id)
    selected_date = request.GET.get('date', str(date.today()))
    
    # Get all slots for the selected date, sorted by start time
    all_slots = ScheduleSlot.objects.filter(doctor=doctor, date=selected_date).order_by('start_time')
    available_slots = all_slots.filter(status='available')
    booked_slots = all_slots.filter(status='booked')

    return render(request, 'clinic/doctor_schedule.html', {
        'doctor': doctor,
        'selected_date': selected_date,
        'available_slots': available_slots,
        'booked_slots': booked_slots
    })
5. Template Example for Schedule Display

Create doctor_schedule.html to visualize the schedule:

<h2>Dr. {{ doctor.user.last_name }}'s Schedule ({{ selected_date }})</h2>

<!-- Date picker to switch between dates -->
<form method="get" class="mb-4">
    <input type="date" name="date" value="{{ selected_date }}" required>
    <button type="submit" class="btn btn-primary">View Date</button>
</form>

<!-- Available Slots -->
<div class="card mb-3">
    <div class="card-header bg-success text-white">
        <h3>Available Slots</h3>
    </div>
    <div class="card-body">
        {% if available_slots %}
            <ul class="list-group">
                {% for slot in available_slots %}
                    <li class="list-group-item d-flex justify-content-between align-items-center">
                        {{ slot.start_time }} - {{ slot.end_time }}
                        <a href="{% url 'book_appointment' slot.id %}" class="btn btn-sm btn-success">Book for Patient</a>
                    </li>
                {% endfor %}
            </ul>
        {% else %}
            <p>No available slots for this date.</p>
        {% endif %}
    </div>
</div>

<!-- Booked Slots -->
<div class="card">
    <div class="card-header bg-warning text-white">
        <h3>Booked Slots</h3>
    </div>
    <div class="card-body">
        {% if booked_slots %}
            <ul class="list-group">
                {% for slot in booked_slots %}
                    <li class="list-group-item">
                        <strong>{{ slot.start_time }} - {{ slot.end_time }}</strong>
                        <br>Patient: {{ slot.linked_appointment.patient_name }}
                        <br>Contact: {{ slot.linked_appointment.patient_contact }}
                        {% if slot.linked_appointment.patient_notes %}
                            <br>Notes: {{ slot.linked_appointment.patient_notes }}
                        {% endif %}
                    </li>
                {% endfor %}
            </ul>
        {% else %}
            <p>No booked slots for this date.</p>
        {% endif %}
    </div>
</div>
Quick Additional Tips
  • Add timezone support in your Django settings to avoid time display issues across regions.
  • Implement a cancel appointment feature that sets the slot status back to available.
  • Add email notifications (using Django’s send_mail) to alert patients and doctors when an appointment is booked or canceled.
  • Restrict access to schedule management views using Django’s permission system to ensure only admins can modify bookings.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 19:12:59