所以我得到了这些任务:
雇员)
首先我创建了一个 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 框架:所以现在是我不明白的部分。创建 session 室仅发布这些值就足够了吗?
创建 session 室后,应如何添加预订?
经过数小时的尝试,我无法正确创建预订并将其分配到特定的 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 添加预订,您需要分两步完成:ReservationViewset
.这假设您已经拥有 Employee
和 MeetingRoom
数据库中的数据。成功POST数据后,响应将返回meeting_id
以及您发布的其他字段值。 meeting_id
是您需要在步骤 2 中发布的预订的 pk。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 室的其他预订发生冲突。这意味着您必须覆盖 clean
或 save
模型中的方法,或 save
序列化程序中的方法。
关于python - Django:尝试使用预订创建 session 室 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64904532/