简体   繁体   English

有没有办法在序列化数据之后只获取查询集中的特定字段,而不在 drf 中创建不同的序列化程序?

[英]Is there a way to get only specific fields in a queryset after serialization data, without create a different serializer in drf?

i need to do a query where i want to get specific fields, then serializate it and keep only the specific fields which I got in the query.我需要在要获取特定字段的地方进行查询,然后对其进行序列化并仅保留我在查询中获得的特定字段。

models.py模型.py

class Search(models.Model):
    NEUTRAL = 'None'
    POSITIVE = 'P'
    NEGATIVE = 'N'
    POLARITY_CHOICES = [
        (NEUTRAL, 'Neutral'),
        (POSITIVE, 'Positive'),
        (NEGATIVE, 'Negative'),
    ]
    user = models.ForeignKey(User,related_name='searched_user_id',on_delete=models.CASCADE)
    word = models.CharField( max_length = 100)
    social_network = models.ForeignKey(SocialNetwork,related_name='search_social_network_id',on_delete=models.CASCADE)
    polarity = models.CharField(
        max_length=4,
        choices=POLARITY_CHOICES,
        default=NEUTRAL,
    )
    sentiment_analysis_percentage = models.FloatField(default=0)
    topic = models.ForeignKey(Topic,related_name='search_topic_id',on_delete=models.CASCADE)
    liked = models.IntegerField(default=0)  
    shared = models.IntegerField(default=0) 
    is_active = models.BooleanField(default=True)
    is_deleted = models.BooleanField(default=False)
    updated_date=models.DateTimeField(auto_now=True)
    searched_date = models.DateTimeField(auto_now_add=True)

serializers.py序列化程序.py

class SearchSerializer(serializers.ModelSerializer):
    searched_date = serializers.DateTimeField(format="%d-%m-%Y")
    class Meta:
        model = Search
        fields = ('__all__')

class RecentSearchSerializer(serializers.ModelSerializer):
    searched_date = serializers.DateTimeField(format="%d-%m-%Y")
    class Meta:
        model = Search
        fields = ('user','social_network','word','searched_date')

class SentimentAnalysisSerializer(serializers.ModelSerializer):
    searched_date = serializers.DateTimeField(format="%d-%m-%Y")
    class Meta:
        model = Search
        fields = ('polarity','searched_date','sentiment_analysis_percentage')

SearchSerializer is the main serializer for search, RecentSearchSerializer is the serializer to pass data and filtering in the DRF api view, and finally I created SentimentAnalysisSerializer to keep the specific fields that I need: SearchSerializer 是搜索的主要序列化器,RecentSearchSerializer 是在 DRF api 视图中传递数据和过滤的序列化器,最后我创建了 SentimentAnalysisSerializer 来保留我需要的特定字段:

api.py api.py

class SearchViewSet(viewsets.ModelViewSet):
    queryset = Search.objects.filter(
        is_active=True,
        is_deleted=False
    ).order_by('id')
    permission_classes = [
        permissions.AllowAny
    ]
    serializer_class = SearchSerializer
    pagination_class = StandardResultsSetPagination

    def __init__(self,*args, **kwargs):
        self.response_data = {'error': [], 'data': {}}
        self.code = 0

    def get_serializer_class(self):
        if self.action in ['recent_search','word_details']:
            return RecentSearchSerializer
        return SearchSerializer

    @action(methods=['post'], detail=False)
    def word_details(self, request, *args, **kwargs):
        try:
            self.response_data['data']['word'] = kwargs['data']['word']
            queryset = Search.objects.filter(
                is_active=True,
                is_deleted=False,
                social_network=kwargs['data']['social_network'],
                user_id=kwargs['data']['user'],
                word=kwargs['data']['word']
            ).order_by('id')
            import pdb;pdb.set_trace()
            serializer = SentimentAnalysisSerializer(queryset, many=True)
            self.response_data['data']['timeline_word_twitter_polarity'] = json.loads(json.dumps(serializer.data))

I did this solution and works good, but is there a way to have the same behaviour without create another serializer?我做了这个解决方案并且效果很好,但是有没有办法在不创建另一个序列化程序的情况下拥有相同的行为? I mean, using SearchSerializer?我的意思是,使用 SearchSerializer?

I tried with the following examples and i got these erros:我尝试了以下示例,但我得到了这些错误:

(Pdb) queryset = Search.objects.filter(is_active=True,is_deleted=False,social_network=kwargs['data']['social_network'],user_id=kwargs['data']['user'],word=kwargs['data']['word']).values('polarity','sentiment_analysis_percentage','searched_date').order_by('id')
(Pdb) serializer = RecentSearchSerializer(queryset, many=True)
(Pdb) self.response_data['data']['timeline_word_twitter_polarity'] = json.loads(json.dumps(serializer.data))
*** KeyError: "Got KeyError when attempting to get a value for field `user` on serializer `RecentSearchSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'user'."
(Pdb) 
(Pdb) queryset = Search.objects.filter(is_active=True,is_deleted=False,social_network=kwargs['data']['social_network'],user_id=kwargs['data']['user'],word=kwargs['data']['word']).values('polarity','sentiment_analysis_percentage','searched_date').order_by('id')
(Pdb) serializer = SearchSerializer(queryset, many=True)
(Pdb) self.response_data['data']['timeline_word_twitter_polarity'] = json.loads(json.dumps(serializer.data))
*** KeyError: "Got KeyError when attempting to get a value for field `word` on serializer `SearchSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'word'."

First I thought that those errors were related with this issue , but according with this answer i'm not passing data parameter like the issue explain, so i can't check what is the error with the Validation method (is_valid())首先我认为这些错误与这个问题有关,但是根据这个答案,我没有像问题解释那样传递data参数,所以我无法检查验证方法的错误(is_valid())

I'm using the last version of DRF: djangorestframework==3.10.3我正在使用 DRF 的最新版本:djangorestframework==3.10.3

I wish to get this result but with SearchSerializer (I need to do other queries with specific fields, i mean I don't need to pass al the fields of Search Model), but I don't know if it's possible我希望得到这个结果,但使用 SearchSerializer (我需要对特定字段进行其他查询,我的意思是我不需要传递 Search Model 的所有字段),但我不知道这是否可能

(Pdb) serializer = SentimentAnalysisSerializer(queryset, many=True)
(Pdb) self.response_data['data']['timeline_word_twitter_polarity'] = json.loads(json.dumps(serializer.data))
(Pdb) self.response_data['data']['timeline_word_twitter_polarity']
[{'searched_date': '09-10-2019', 'polarity': 'P', 'sentiment_analysis_percentage': 0.0}, {'searched_date': '09-10-2019', 'polarity': 'N', 'sentiment_analysis_percentage': 0.0}]

Thanks in advance, any help will be appreciated.在此先感谢,任何帮助将不胜感激。

Well, the errors are clear.好吧,错误很明显。

You limit the query to return only certain fields using values .您将查询限制为使用values仅返回某些字段。 So then the serializer cannot serialize it because many are missing.因此,序列化程序无法序列化它,因为很多都丢失了。

However, the following approach should work for you.但是,以下方法应该适合您。

Note: I am not fan of this - i would rather have 2 separate serializers like you do.注意:我不喜欢这个 - 我宁愿像你一样拥有 2 个单独的序列化器。 But it might help you.但它可能会帮助你。

class SearchSerializer(serializers.ModelSerializer):
    searched_date = serializers.DateTimeField(format="%d-%m-%Y")
    class Meta:
        model = Search
        fields = ('__all__')

    def __init__(self, instance=None, data=empty, **kwargs):
        super(SearchSerializer, self).__init__(instance, data, **kwargs)
        if instance is not None and instance._fields is not None:     
            allowed = set(instance._fields)
            existing = set(self.fields.keys())
            for fn in existing - allowed:
                self.fields.pop(fn)

Basically, it keeps only fields from the provided instance .基本上,它只保留提供的instance中的字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SlugRelatedField中用于DRF序列化程序的特定查询集 - Specific queryset in SlugRelatedField for DRF serializer DRF序列化器深度使创建时忽略字段 - DRF serializer depth makes fields ignored on create 有什么方法可以将一些特定字段从序列化程序获取到另一个序列化程序? - Is there any way to get some specific fields from a serializer to another serializer? 获取和发布时序列化程序中的 DRF 其他字段 - DRF other fields in serializer on get and on post drf 使用不同的序列化程序显示“访问 `serializer.data` 后无法调用 `.save()` - drf use different serializer show 'You cannot call `.save()` after accessing `serializer.data` DRF 如何选择特定字段以在嵌套的序列化器关系中显示? (没有额外的序列化器) - DRF How to select specific fields to display in a nested serializer relationship? (without additional serializers) 可以访问序列化程序验证的数据DRF - get access to serializer validated data DRF DRF:如何根据实例属性使序列化器字段不同 - DRF: How to make serializer fields different depending on instance attributes 如何从视图中分配 DRF 序列化程序只读字段 - How to assign DRF serializer read_only fields from views 仅使用queryset方法时,DRF响应会返回所有字段 - DRF Response returning all fields when using queryset method only
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM