[英]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.