Django 多态模型序列化程序

Django 多态模型序列化程序,django,django-rest-framework,django-polymorphic,Django,Django Rest Framework,Django Polymorphic,我正在使用一个模型来设置通知: 我的模型: class Notification(PolymorphicModel): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) created_by = models.ForeignKey(ElsUser, on_delete=models.CASCADE, default=None, related_name="creatednotif

我正在使用一个模型来设置通知:

我的模型:

class Notification(PolymorphicModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_by = models.ForeignKey(ElsUser, on_delete=models.CASCADE, default=None, related_name="creatednotifications")
    created_on = models.DateTimeField(default=timezone.now)
    created_for = models.ForeignKey(ElsUser, on_delete=models.CASCADE, default=None, related_name="receivednotifications")
    read = models.DateTimeField(default=None, null=True, blank=True)
    message = models.CharField(default=None, blank=True, null=True, max_length=800)

    @property
    def total(self):
        return self.objects.filter(created_for=self.request.user).count()

    @property
    def unread(self):
        return self.objects.filter(created_for=self.request.user,read=None).count()

    @property
    def read(self):
        return self.objects.filter(created_for=self.request.user).exclude(read=None).count()    

class WorkflowNotification(Notification):
    # permission_transition = models.ForeignKey(WorkflowStatePermissionTransition, on_delete=models.CASCADE)
    action = models.ForeignKey(UserAction, on_delete=models.CASCADE)
目前,我只有一个从多态模型继承的模型WorkFlowNotification,但将来会有很多

我正在尝试在API中获取登录用户的通知总数。total作为属性字段提供,以在相同情况下提供帮助

我的序列化程序:

class NotificationSerializer(serializers.ModelSerializer):
    total = serializers.ReadOnlyField()
    read = serializers.ReadOnlyField()
    unread = serializers.ReadOnlyField()

    class Meta:
        model = Notification
        fields = ['id', 'total','read', 'unread']
他认为:

   class NotificationsMeta(generics.ListAPIView):
    serializer_class = NotificationSerializer
    queryset = Notification.objects.all()
当我尝试运行服务器时,它显示:

  Got AttributeError when attempting to get a value for field `total` on serializer `NotificationSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `WorkflowNotification` instance.
Original exception text was: Manager isn't accessible via WorkflowNotification instances.

我不确定调用负责在模型中查询的模型属性如何从序列化程序中提供适当的数据。不幸的是,我在这方面确实存在知识差距。我正在考虑另一种解决办法。我希望下面的方法能奏效

class NotificationSerializer(serializers.ModelSerializer):
    total = serializers.serializers.SerializerMethodField()

    read = serializers.ReadOnlyField()
    unread = serializers.ReadOnlyField()

    class Meta:
        model = Notification
        fields = ['read', 'unread']


    def get_total(self, obj):
        user =  self.context['request'].user 
        return Notification.objects.filter(created_for=user).count()
如果这项工作,那么你可以做类似的事情,读和未读的

为了获取当前用户的通知,我们需要覆盖视图中的get_queryset。
既然您只需要“元数据”,那么创建模型序列化程序有什么用呢?或者任何序列化程序?序列化程序将为您提供模型对象的序列化实例。因此,如果您有多个对象,您将得到多个序列化对象作为响应

让你的观点正常点。因为没有必要序列化任何内容

class NotificationsMeta(APIView):
    def get(self, request, format=None):
        qs = Notification.objects.filter(created_for=self.request.user)
        response = {
            'total': qs.count(),
            'read': qs.filter(read=None).count(),
            'unread': qs.exclude(read=None).count()
        }
        return Response(response)
现在从模型中删除这些属性函数


我没有测试您的查询,只是从您的模型中复制了它们。您需要检查它们是否工作正常。希望这有帮助。

这只是跳过了整个字段。.只有id在玩!您是否处理过多态模型?我只关心一个问题,您已经在序列化程序中传递了一个筛选查询集,为什么要在模型属性中进行筛选。我做了模型多态性的工作,但不久前。我不这样做,我甚至需要在这个API的listAPI视图,因为我只想登录的用户看到他的总,未读和已读notifications@MohitHarshan我已经更新了我的答案。我对你要找的东西有一个了解的缺口。请检查。嘿,这将起作用..但我为用户创建了两个通知..因此两个对象正在返回..我只需要一个对象,如{total:300,unread:100,read:200,page_size:50}
class NotificationsMeta(APIView):
    def get(self, request, format=None):
        qs = Notification.objects.filter(created_for=self.request.user)
        response = {
            'total': qs.count(),
            'read': qs.filter(read=None).count(),
            'unread': qs.exclude(read=None).count()
        }
        return Response(response)