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

Django REST framework如何根据当前时间返回物品已预订/空闲状态

实现方案

首先修正你现有代码的两处笔误:

  1. Items模型中选项变量名不匹配:定义的是ITEMS_CATEGORIES,字段调用时写的是ITEM_CATEGORIES
  2. Booking模型的item外键关联对象错误,你写的Subsystem应该是Items

方案1:物品列表展示状态(适配你的需求场景)

你需要展示所有物品的当前状态,因此直接针对Items模型做状态判断和序列化即可:

步骤1:修改Items模型增加状态判断逻辑

from django.utils import timezone

class Items(models.Model):
    ITEMS_CATEGORIES=(
        ('item-1', 'item-1'),
        ('item-2', 'item-2'),
        ('item-3', 'item-3'),
        ('item-4', 'item-4'),
        ('item-5', 'item-5'),
    ) 
    category = models.CharField(max_length=10, choices=ITEMS_CATEGORIES) # 原max_length=5不够,item-x长度为6
    def __str__(self):
        return self.category
    
    # 新增状态属性
    @property
    def current_status(self):
        now = timezone.now()
        # 判断当前物品是否有正在生效的预约
        has_active_booking = self.booking_set.filter(
            check_in__lte=now,
            check_out__gte=now
        ).exists()
        return "booked(已预订)" if has_active_booking else "free(空闲)"

步骤2:编写物品状态序列化器

from rest_framework import serializers
from .models import Items

class ItemStatusSerializer(serializers.ModelSerializer):
    status = serializers.CharField(source='current_status', read_only=True)
    # 可选:增加当前预约人字段
    current_booking_user = serializers.SerializerMethodField(read_only=True)
    
    class Meta:
        model = Items
        fields = ('id', 'category', 'status', 'current_booking_user')
    
    def get_current_booking_user(self, obj):
        now = timezone.now()
        active_booking = obj.booking_set.filter(
            check_in__lte=now,
            check_out__gte=now
        ).first()
        return active_booking.user if active_booking else None

步骤3:视图调用示例

from rest_framework import viewsets
from .models import Items
from .serializers import ItemStatusSerializer

class ItemStatusViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Items.objects.all()
    serializer_class = ItemStatusSerializer

返回数据示例:

[
    {
        "id": 1,
        "category": "item-1",
        "status": "free(空闲)",
        "current_booking_user": null
    },
    {
        "id": 2,
        "category": "item-2",
        "status": "booked(已预订)",
        "current_booking_user": "张三"
    }
]

方案2:预约列表附带物品状态

如果你确实需要在预约记录的序列化结果中附加对应物品的当前状态,按以下实现:

from rest_framework import serializers
from django.utils import timezone
from .models import Booking

class BookingSerializer(serializers.ModelSerializer):
    item_current_status = serializers.SerializerMethodField(read_only=True)
    class Meta:
        model = Booking
        fields = ('item','check_in','check_out', 'user', 'item_current_status')
    
    def get_item_current_status(self, obj):
        now = timezone.now()
        return "booked(已预订)" if obj.check_in <= now <= obj.check_out else "free(空闲)"

注意:不要直接用datetime.datetime.now(),Django开启时区支持时这个方法返回的是无时区信息的时间,和数据库存储的带时区时间对比会报错,必须用django.utils.timezone.now()获取当前时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:21:01