Django:尝试创建带有预订的会议室API

2024-04-26 20:20:19 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我得到了这些任务:

  • 创建会议室

  • 获得会议室预订和按员工筛选的可能性

  • 创建预订(预订具有标题、起始日期和截止日期, (雇员)

首先,我创建了一个会议室,这是一个模型:

class MeetingRooms(models.Model):
    public_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True, blank=False, null=False, max_length=36)

    creator = models.ForeignKey(Employees, on_delete=models.CASCADE)
    reservations = models.ManyToManyField(MeetingRoomsReservations, blank=True)
    secret_key = models.CharField(max_length=128, null=False, blank=False)
    date_created = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = "MeetingRooms"

    def __str__(self):
        return str(self.id)

正如任务所说,我需要创建某种保留,所以基本上我认为我可以创建reservations对象并将其设置为ManyToManyField,这样它就可以为不同的用户提供许多保留,想象一下会议可能有10个人

然后我创建了MeetingRoomsReservations模型来处理所有预订:

class MeetingRoomsReservations(models.Model):
    statusTypes = [
        (0, "Valid"),
        (1, "Cancelled")
    ]

    receiver = models.ForeignKey(Employees, on_delete=models.CASCADE)
    meeting_room = models.ForeignKey('MeetingRooms', on_delete=models.CASCADE, default=None)
    title = models.CharField(max_length=150, blank=False, null=False)
    status = models.IntegerField(choices=statusTypes, null=False, blank=False, default=0)

    date_from = models.DateTimeField()
    date_to = models.DateTimeField()


    class Meta:
        db_table = "MeetingRoomsReservations"

    def __str__(self):
        return str(self.id)

据我所知,会议室预订将处理为会议室登记的所有预订

会议室>;预订>;[预订列表]=每个预订都有时间等

好的,现在我必须创建API端点:

from main.models import MeetingRooms, MeetingRoomsReservations
from rest_framework import viewsets, generics
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, AllowAny
from .serializers import MeetingRoomSerializer, ReservationSerializer

from django.http import JsonResponse

class MeetingRoomViewSet(viewsets.ModelViewSet):

    permission_classes = [
        AllowAny
    ]

    queryset = MeetingRooms.objects.all()
    serializer_class = MeetingRoomSerializer

    def perform_create(self, serializer):
        serializer.save()


class ReservationViewSet(viewsets.ModelViewSet):

现在剩下的是创建一个序列化程序?听起来容易吗?让我想想

从rest_框架导入序列化程序 从main.models导入会议室、会议室保留

class ReservationSerializer(serializers.ModelSerializer):
  class Meta:
    model = MeetingRoomsReservations
    fields = ('receiver', 'meeting_room', 'status', 'title', 'date_from', 'date_to')


class MeetingRoomSerializer(serializers.ModelSerializer):
  class Meta:
    model = MeetingRooms
    fields = ('creator', 'public_id', 'creator', 'date_created', 'secret_key', 'reservations')
    extra_kwargs = {'secret_key': {'write_only': True, 'min_length': 8}}

让我们看看我们的Rest框架:

enter image description here

所以现在是我不明白的部分。要创建会议室,仅发布这些值就足够了吗

enter image description here

创建会议室后,应如何添加预订

enter image description here

经过数小时的尝试,我无法正确创建预订并将其分配到特定的会议室。如何正确处理此操作


Tags: fromimportselfidfalsetruedatemodels
1条回答
网友
1楼 · 发布于 2024-04-26 20:20:19

让我帮助您克服设计模型的最初障碍,因为您似乎在一些模型中有一些不应该存在的字段。我们从两个实体开始:员工和会议室。员工将有一个基本的员工ID、名字和姓氏。会议室将具有用于内部索引的ID,以及唯一的会议室编号。这个房间号类似于您在公司办公室会议室中看到的房间号。房间号可能有字母字符,因此我们的字段将是CharField

为了遵循您的一些设计约定,我将在所有模型中使用UUIDField作为primary_key字段。另外,为了简洁起见,我只添加了一些字段,作为一个最简单的可行示例来演示实体。您可以根据需要自由添加更多内容

class Employee(models.Model):
    employee_id = models.UUIDField(
        default=uuid.uuid4,
        primary_key=True,
        editable=False
    )
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)


class MeetingRoom(models.Model):
    room_id = models.UUIDField(
        default=uuid.uuid4,
        primary_key=True,
        editable=False
    )
    room_number = models.CharField(
        max_length=16,
        unique=True
    )

好的,现在让我们关注预订的实现。根据需求规格,员工应该能够进行预订,我们应该能够获取预订并按员工进行筛选。此外,预订要求员工在一定时间范围内在该房间组织会议,并邀请员工参加。这些被邀请者可以选择是否接受邀请。跟踪被邀请者是否接受邀请意味着我们还需要^{上的表。让我们为受邀者制作一个Reservation模型和ManyToManyField上的

class Reservation(models.Model):
    STATUS_VALID = 0
    STATUS_CANCELLED = 1
    STATUS_TYPES = [
        (STATUS_VALID, "Valid"),
        (STATUS_CANCELLED, "Cancelled"),
    ]

    meeting_id = models.UUIDField(
        default=uuid.uuid4,
        primary_key=True,
        editable=False
    )
    room = models.ForeignKey(
        MeetingRoom,
        related_name="reservations",
        on_delete=models.CASCADE
    )
    organizer = models.ForeignKey(
        Employee,
        related_name="organized_reservations",
        on_delete=models.CASCADE
    )
    invitees = models.ManyToManyField(
        Employee,
        through="ReservationInvitee"
    )
    title = models.CharField(max_length=150)
    status = models.IntegerField(
        choices=STATUS_TYPES,
        default=STATUS_VALID
    )
    date_from = models.DateTimeField()
    date_to = models.DateTimeField()


class ReservationInvitee(models.Model):
    IS_PENDING = -1
    IS_ATTENDING = 1
    IS_NOT_ATTENDING = 0
    ATTENDING_STATUSES = [
        (IS_PENDING, "Pending"),
        (IS_ATTENDING, "Attending"),
        (IS_NOT_ATTENDING, "Not attending")
    ]

    reservation = models.ForeignKey(
        Reservation,
        on_delete=models.CASCADE
    )
    employee = models.ForeignKey(
        Employee,
        related_name="invited_reservations",
        on_delete=models.CASCADE
    )
    status = models.IntegerField(
        choices=ATTENDING_STATUSES,
        default=IS_PENDING
    )

从这里开始,它定义了ReservationReservationInvitee的API序列化程序和视图。我不会为EmployeeMeetingRoom定义序列化程序和视图,因为它们对于这个实现并不重要。我把它作为练习留给你做

class ReservationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Reservation
        fields = (
            "meeting_id",
            "room",
            "organizer",
            "invitees",
            "title",
            "status",
            "date_from",
            "date_to",
        )
        read_only_fields = (
            "meeting_id",
            "invitees",
        )


class ReservationInviteeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ReservationInvitee
        fields = "__all__"
        read_only_fields = ('id',)


class ReservationViewset(viewsets.ModelViewSet):
    queryset = Reservation.objects.all()
    serializer_class = ReservationSerializer


class ReservationInviteeViewset(viewsets.ModelViewSet):
    queryset = ReservationInvitee.objects.all()
    serializer_class = ReservationInviteeSerializer

现在,要通过API添加预订,需要分两步进行:

  1. 将数据发布到ReservationViewset。这假设您的数据库中已经有EmployeeMeetingRoom数据。成功发布数据后,响应将返回meeting_id以及您发布的其他字段值。meeting_id是您需要在步骤2中发布的预订的主键
  2. 将数据与被邀请者一起发布到ReservationInviteeViewset,其中包括步骤1中自动生成的meeting_id的pk。将受邀参加会议的受邀者的数据发布到此端点

当被邀请者接受/拒绝会议邀请时,您可以简单地将新的有效负载放在ReservationInviteeViewset端点上

现在有一个关于按员工筛选预订的问题,我假设是由组织会议的员工进行的。在这种情况下,可以使用docs中指定的过滤技术。我将通过query parameters as an example使用它们的筛选:

class ReservationViewset(viewsets.ModelViewSet):
    serializer_class = ReservationSerializer

    def get_queryset(self):
        queryset = Reservation.objects.all()
        employee = self.request.query_params.get('employee_id', None)
        if employee is not None:
            queryset = queryset.filter(organizer__employee_id=employee)
        return queryset

这应该是一个很好的起点。还有许多其他功能可以增强,例如显示ReservationSerializerReservationInvitee详细信息。如果你想达到这个目的,你可以阅读this post。其他增强功能包括date_fromdate_to字段的验证,以便它们不会与该会议室的另一个预订冲突。这意味着您必须重写模型中的cleansave方法,或序列化程序中的save方法

相关问题 更多 >