如何在一个 viewset/serializer 中使用多个模型?

How to use multiple models inside one viewset/serializer?

我的系统中有 2 个项目我必须 use.But 我正在尝试开发一个系统,我必须将它们放在一个视图中并按“时间戳”对它们进行排序。

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 个或模型合并到一个视图集或序列化程序中?

注意:我知道在Whosebug中有一些类似问题的答案,但我的代码结构不同,我想得到一些观点

更新

所以这是我想做的: -我正在形成一个类似 facebook/instagram 的提要页面,并在一个视图中组合多个模型。

-我已经可以用上面的视图集来做,但我现在想合并它们。

-我想按时间戳对每个项目进行排序,并在 JSON 内检索它们,但在一个系统内,而不是像 :

calendarevents:[] calendaritems []

但喜欢:

calendarevent 1(created 2 mins ago)
calendaritem 1 (created 3 mins ago)
calendarevent 2(created 4 mins ago) 
calendaritem 2(created 5 mins ago)

我很乐意提供更多信息,欢迎提问。

更新 2:

class CalendarEvent(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    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)

class CalendarItem(models.Model):


    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    author = models.ForeignKey(User,  on_delete=models.CASCADE,related_name='calendaritems')
    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)


您可以使用 APIView 和通用 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]CalendarEventCalendarItem 创建父模型,其中可以在父模型中定义它们拥有的公共字段:

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']

有了这些,您可以通过父 CalendarFeed.

列出所有 CalendarEventCalendarItem