Мне нужно сделать запрос, в котором я хочу получить определенные поля, затем сериализовать его и сохранить только те поля, которые я получил в запросе.
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 - это основной сериализатор для поиска, RecentSearchSerializer - это сериализатор для передачи данных и фильтрации в представлении API DRF, и, наконец, я создал 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'."
Сначала я подумал, что эти ошибки были связаны с этой проблемой , но в соответствии с этим ответом я не передаю data
параметр, подобный объяснению проблемы, поэтому я не могу проверить, что является ошибкой с помощью метода проверки (is_valid())
Я использую последнюю версию DRF: djangorestframework == 3.10.3
Я хочу получить этот результат, но с SearchSerializer (мне нужно сделать другие запросы с конкретными полями,я имею в виду, что мне не нужно передавать все поля модели поиска), но я не знаю, возможно ли это
(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}]
Заранее спасибо, любая помощь будет оценена.