python - Django:尝试使用预订创建 session 室 API

标签 python django api django-models django-rest-framework

所以我得到了这些任务:

  • 创建 session 室
  • 获取 session 室预订和按员工过滤的可能性
  • 创建预订(预订有标题、起止日期、
    雇员)

  • 首先我创建了一个 session 室,这是模型:
    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 object 并使其成为 ManyToManyField,因此它可以为不同的用户提供许多预订服务,想象一下 session 可能有 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)
    
    就我理解的逻辑而言,MeetingRoomsReservations 将处理为 MeetingRoom 注册的所有预订。
    MeetingRoom > Reservations > [ List Of Reservations ] = 每个预订都有时间等。
    好的,现在我必须创建 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_framework 导入序列化程序
    从 main.models 导入 MeetingRooms、MeetingRoomsReservations
    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
    所以现在是我不明白的部分。创建 session 室仅发布这些值就足够了吗?
    enter image description here
    创建 session 室后,应如何添加预订?
    enter image description here
    经过数小时的尝试,我无法正确创建预订并将其分配到特定的 session 室。我该如何正确处理这个操作?

    最佳答案

    让我帮助您克服设计模型的最初障碍,因为您在某些模型中似乎有一些不应该存在的字段。我们从 2 个实体开始:员工和 session 室。员工将有一个基本的员工 ID、名字和姓氏。 session 室将具有用于内部索引的 ID 以及唯一的房间号。此房间号类似于您在公司办公室的 session 室中看到的房间号。房间号可能有字母字符,所以我们的字段将是 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
        )
    
    好的,现在让我们专注于预订实现。根据需求规范,员工应该能够进行预订,我们应该能够获取预订并按员工进行过滤。此外,预订需要员工在某个时间范围内在该房间组织 session ,并且会有员工作为受邀者。这些受邀者可以选择接受或不接受邀请。跟踪受邀者是否接受邀请意味着我们还需要在 ManyToManyField 上有一个直通表。 .让我们做一个 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
        )
    
    从这里开始,它定义了 Reservation 的 API 序列化程序和 View 。和 ReservationInvitee .我不会为 Employee 定义序列化程序和 View 和 MeetingRoom因为它们对于这个实现并不是那么重要。我会把它留给你做的练习。
    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 添加预订,您需要分两步完成:
  • POST 数据到 ReservationViewset .这假设您已经拥有 EmployeeMeetingRoom数据库中的数据。成功POST数据后,响应将返回meeting_id以及您发布的其他字段值。 meeting_id是您需要在步骤 2 中发布的预订的 pk。
  • POST 数据到 ReservationInviteeViewset包括 meeting_id 的自动生成的 pk从第 1 步开始,与受邀者一起。将数据发布到此端点,用于邀请参加 session 的受邀者。

  • 当受邀者接受/拒绝 session 邀请时,您可以简单地将新的有效负载放到 ReservationInviteeViewset 上。端点。
    现在是关于按员工过滤预订的问题,我假设由组织 session 的员工负责。在这种情况下,您可以使用 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
    
    这对您来说应该是一个很好的起点。您还可以增强许多其他内容,例如显示 ReservationInvitee ReservationSerializer 的详细信息.您可以阅读 this post如果你想实现这一点。其他增强功能包括对 date_from 的验证和 date_to字段,以便它们不会与该 session 室的其他预订发生冲突。这意味着您必须覆盖 cleansave模型中的方法,或 save序列化程序中的方法。

    关于python - Django:尝试使用预订创建 session 室 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64904532/

    相关文章:

    javascript - 数据表 - 排序图标复制

    django - 如何在 django 管理面板中对用户进行统计,并在相关字段上进行日期过滤器?

    python - Django 的 DRY 方法

    java - 如何仅使用官方 api 来学习 java?

    php - 在没有设置 Laravel 数据库时返回插入 ID

    android - 我如何使用测试帐户进入 Android 中的 Paypal 沙箱?

    python - 如何从 CMake 获取 "install"Python 代码?

    python - 如何重新安装损坏的python包

    python - 国际象棋编程的走棋和撤棋

    python - 从 Python 数据框中文本列中的特定单词创建虚拟变量和分类变量