我需要在要获取特定字段的地方进行查询,然后对其进行序列化,并仅保留查询中获得的特定字段。
models.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
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是用于搜索的主要序列化器,最近搜索器是在DRF api视图中传递数据和过滤的序列化器,最后我创建了SentimentAnalysisSerializer来保留我需要的特定字段:
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))
我做了这个解决方案并且效果很好,但是有一种方法可以在不创建另一个序列化程序的情况下具有相同的行为?我的意思是,使用SearchSerializer?
我尝试了以下示例,但得到了这些错误提示:
(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'."
首先,我认为这些错误与此issue有关,但是根据此answer我没有像问题说明那样传递data
参数,所以我无法检查Validation method (is_valid())
我正在使用DRF的最新版本:djangorestframework == 3.10.3
我希望得到这个结果,但是要使用SearchSerializer(我需要对特定字段进行其他查询,我的意思是我不需要传递搜索模型的所有字段),但是我不知道是否可能< / p>
(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}]
在此先感谢您的帮助。
答案 0 :(得分:1)
嗯,错误很明显。
使用values
将查询限制为仅返回某些字段。因此,串行器无法序列化,因为缺少许多。
但是,以下方法应该适合您。
注意:我不喜欢这个-我宁愿像您一样拥有2个单独的序列化器。但这可能会对您有所帮助。
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)
基本上,它仅保留提供的instance
中的字段。