在使用Django Rest ModelSerializer序列化数据时,如何拒绝queryset对象?

2024-10-04 11:22:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个查询集,我正试图用继承Django REST Framework ModelSerializer类的CasePartySerializer序列化它。它有一个名为CaseRuleDocketSerializer的嵌套序列化程序

下面是我如何实例化它的

def get_queryset(self):

    self.queryset = CaseParty.objects.filter(user=self.request.user)

def get(self):
    serial = CasePartySerializer(
        list(
            self.queryset[
                self.offset:self.offset + self.limit
            ]
        ), 
        many=True, 
        context={
            'tracked': self.tracked.value,
            'request': self.request
        }
    )

很简单,但是如果我想有条件地传递和拒绝对象,使它们不包含在最终确定的serial.data中,该怎么办呢

我确信我可能会提出一些异常,这些异常会传递给这个数据库对象,但我不确定会是什么。我很幸运地查阅了文件;考虑到REST框架文档的质量,我感到非常惊讶。我可能错过了一些简单的东西

这是我的CasePartySerializer,你可以看到我的条件句。在本例中,您可以看到它们基于嵌套序列化程序CaseRuleDocketSerializer输出的结果,该输出在get_queryset方法中不可用。如果其中一个ruledocket项为“红色”,则不需要将其包含在序列化程序结果中。我知道我也可以在get_queryset方法中进行过滤,但似乎在序列化程序本身中进行过滤会更容易

class CaseRuleDocketSerializer(serializers.ModelSerializer):
    
    table_row_color = serializers.SerializerMethodField()
    
    class Meta:
        model = CaseRuleDocket
        fields = [
            'unique_id',
            'created_date',
            'updated_date',
            'date_time',
            'entry',
            'party'
        ]

    def get_is_user_only_created(self, obj):

        if obj.is_user_created and not obj.is_court_created:
            return 'green' 
        elif obj.is_court_created and not obj.is_user_created:
            return 'blue'
        else:
            return 'red'

class CasePartySerializer(serializers.ModelSerializer):

    docket_of_party = CaseRuleDocketSerializer(many=True, read_only=True)
    table_row_color = serializers.SerializerMethodField()

    class Meta:
        model = CaseParty
        fields = [
            'is_tracked',
            'created_date',
            'updated_date',
            'serve_status',
            'serve_status_date',
            'defendant',
            'plaintiff',
            # CONTINUE WITH THE REST OF THE FIELDS....
        ]

    def get_table_row_color(self, obj):

        errors = [
            x.table_row_color for x in self.obj.docket_party
        ]

        if 'blue' in errors:
            return 'blue'
        elif 'green' in errors:
            return 'green'
        else:
            # HERE IS WHERE I WANT TO EXCEPT AND REMOVE 
            # THIS CaseParty OBJECT INSTANCE
 
  

我已经使用stackoverflow很多年了,我总能找到我需要的答案。由于某种原因,我找不到一种方法来正确地阐述这个问题。此外,我熟悉文档,并已彻底阅读。如果由于效率、可读性或其他原因,我不建议在查询集内部进行筛选,请在回答中说明原因

如果你需要澄清,请告诉我

谢谢


Tags: self程序objgetdatereturn序列化is
1条回答
网友
1楼 · 发布于 2024-10-04 11:22:15

根据您的示例,您正在筛选没有相关CaseTrack模型的所有CaseParty实例,最好的方法是更新视图的get_queryset方法

基本上,您可以编写自己的get_queryset(self)方法来过滤掉不需要的模型,而不是使用queryset = CaseParty.objects.all()

举一个更具体的例子:

class MyViewSet(ModelViewSet):
    
    def get_queryset(self):
        # We fetch all party instances
        party_instances = CaseParty.objects.all()
        # We fetch all case_tracks linked to them
        case_tracks = CaseTrack.objects.get(
                user=self.request.user, 
                case__in=party_instances
            )
        # We extract the party ids from case tracks
        party_ids_from_casetracks = {item.case.id for item in case_tracks}
        # We only keep those parties in the queryset
        party_instances_with_tracks = [item for item in party_instances if item.id in party_ids_from_casetracks ]
        return party_instances_with_tracks 

您将在the official documentation中找到更多示例

如果由于不同的端点/视图必须具有不同的过滤器,因此在视图集级别进行过滤有问题,则只需在视图操作中进行过滤即可

正如其他人在评论中提到的,序列化程序不是用来过滤数据的:

  • 视图过滤数据(queryset、get_queryset、filter_queryset、detail视图等)
  • 序列化程序接收数据、验证数据、创建/更新/销毁实例、返回表示和内部值

相关问题 更多 >