Как использовать несколько моделей в одном наборе представлений/сериализаторе?
У меня есть 2 элемента в моей системе, которые я должен использовать. Но я пытаюсь разработать систему, в которой я должен получить их в одном представлении и упорядочить их по "временной метке".
class CalendarEventSerializer(serializers.ModelSerializer):
class Meta:
model = CalendarEvent
fields = ("id","author",...)
class CalendarItemSerializer(serializers.ModelSerializer):
class Meta:
model = CalendarItem
fields = ("id","author",...)
Я использую ViewSet для регулирования моих моделей для постраничного просмотра и фильтрации.
class CalendarItemViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
queryset = CalendarItem.objects.all().order_by('-timestamp')
serializer_class = CalendarItemSerializer
filter_backends = [UserFilterBackend,DjangoFilterBackend]
pagination_class = StandardResultsSetPagination
filterset_fields = ['author']
class CalendarEventViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
queryset = CalendarEvent.objects.all().order_by('-timestamp')
serializer_class = CalendarEventSerializer
filter_backends = [UserFilterBackend,DjangoFilterBackend]
pagination_class = StandardResultsSetPagination
filterset_fields = ['author']
Как я могу использовать эту систему для объединения 2 или моделей в один viewset или сериализатор подобным образом?
Примечание: я знаю, что на подобные вопросы есть ответы в stackoverflow, но структура моего кода отличается, я хочу получить несколько точек зрения
Вы можете настроить вход с помощью APIView и Generic APIVIEW
Вот один из способов достижения того, чего вы пытаетесь достичь.
class GetCalenderEventAndItemsAPIView(APIView, GenericAPIView):
permission_classes = (IsAuthenticated,)
item_queryset = CalendarItem.objects.all().order_by('-timestamp')
event_queryset = CalendarEvent.objects.all().order_by('-timestamp')
item_serializer_class = CalendarItemSerializer
event_serializer_class = CalendarEventSerializer
filterset_fields = ['author']
def get_paginated_query(self, _query_set):
page = self.paginate_queryset(self.filter_queryset(_query_set))
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
return page
def get(self, request, *args, **kwargs):
event_serializer = self.event_serializer_class(self.get_paginated_query(self.event_queryset),
many=True)
item_serializer = self.event_serializer_class(self.get_paginated_query(self.item_queryset), many=True)
response_results = {
"calendarevents": event_serializer.data,
"calendaritems": item_serializer.data
}
return Response(response_results)
Это поможет вам в правильном направлении. Просто поиграйте с приведенным выше способом.
Другой способ подойти к этому - использовать multi-table inheritance...[Django-doc] для создания родительской модели для CalendarEvent и CalendarItem, где общие поля, которые они имеют, могут быть определены в родительской модели:
class CalendarFeed(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE,related_name='calendarevents')
charfield1 = models.CharField(max_length=300)
integerfield1 = models.IntegerField(default='0')
charfield2 = models.CharField(max_length=200,null=True, blank=True)
charfield3 = models.CharField(null=True,blank=True,max_length=64000)
timestamp = models.DateTimeField(auto_now_add=True)
class CalendarEvent(CalendarFeed):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
class CalendarItem(CalendarFeed):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
Тогда вы можете просто создать сериализатор и набор представлений, который фиксирует все CalendarFeed следующим образом:
class CalendarFeedSerializer(serializers.ModelSerializer):
class Meta:
model = CalendarFeed
fields = "__all__"
class CalendarFeedViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
queryset = CalendarFeed.objects.all().order_by('-timestamp')
serializer_class = CalendarFeedSerializer
filter_backends = [UserFilterBackend, DjangoFilterBackend]
pagination_class = StandardResultsSetPagination
filterset_fields = ['author']
С их помощью можно перечислить все CalendarEvent и CalendarItem через родительский CalendarFeed.