#django-models #django-rest-framework #django-views #django-serializer
Вопрос:
Я пытаюсь создать приложение для обмена сообщениями с помощью django-rest-фреймворка. На мой взгляд, у меня возникла проблема при возврате ответа. С текущим кодом, показанным выше, когда я размещаю запрос get, я получаю:
{
"non_field_errors": [
"Invalid data. Expected a dictionary, but got SerializerMetaclass."
]
}
Немного дополнительной информации…
Я думаю, что ошибка как-то связана с моим множеством полей в моей модели общения, но я могу ошибаться.
Поле участники в моей модели общения имеет отношение «многие ко многим» к пользователям. (В разговоре может быть 2 пользователя, но у пользователя может быть любое количество разговоров)
class Message(models.Model):
message_id = models.AutoField(primary_key=True)
conversation_id = models.ForeignKey(to=Conversation, null=False, blank=False, on_delete=models.CASCADE)
message_body = models.TextField(null=False)
sender_id = models.ForeignKey(to=User,to_field='id', on_delete=models.CASCADE)
sent_date = models.CharField(max_length=400, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return str(self.message_id)
class Conversation(models.Model):
conversation_id = models.AutoField(primary_key=True)
participants = models.ManyToManyField(to=User)
created_at = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
convo_id = self.conversation_id
return 'Conversation ' str(convo_id)
class ConversationSerializer(serializers.ModelSerializer):
other_username = serializers.CharField(read_only=True)
other_user_email = serializers.CharField(read_only=True)
latest_message = serializers.CharField(read_only=True)
participants = UsersSerializer(many=True, read_only=True)
class Meta:
model = Conversation
fields = ['conversation_id', 'participants','other_username','other_user_email','latest_message']
def get_current_user(self, obj):
request = self.context.get('request',None)
if request == None:
raise ValueError('No request object')
return request.user
def get_other_user_id(self, current_user_id, participants):
for id in participants:
if current_user_id != id:
return id
def get_latest_message(self, conversation_id):
latest_message = Message.objects.filter(conversation_id=conversation_id).latest()
message_body = latest_message.message_body
sent_date = latest_message.sent_date
latest_message = {
'message_body': message_body,
'sent_date': sent_date,
'is_read': True
}
return latest_message
def validate(self, data):
conversation_id = data.get('conversation_id')
participants = data.get('participants', ' ')
current_user = self.get_current_user()
current_user_id = current_user.id
other_user_id = self.get_other_user_id(current_user_id=current_user_id,participants=participants)
latest_message = self.get_latest_message()
other_user = User.objects.get(id=other_user_id)
other_username = other_user.username
other_user_email = other_user.email
if other_user is None:
raise ValidationError('Could not get other user')
new_data = {
'conversation_id': conversation_id,
'other_username': other_username,
'other_user_email': other_user_email,
'latest_message': latest_message,
}
return new_data
class GetConversationView(GenericAPIView):
serializer_class = ConversationSerializer
authentication_classes = []
permission_classes = [AllowAny]
queryset = Conversation.objects.all()
def get_queryset(self):
return self.queryset.all()
def get(self, request):
queryset = self.get_queryset()
serializer = self.serializer_class(data=ConversationSerializer)
if serializer.is_valid():
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Комментарии:
1.
serializer = self.serializer_class(data=ConversationSerializer)
в этой строке вы передаете сам класс сериализатора для сериализации сериализатора. Похоже, что вы собираетесь передать списокConversation
объектов, так что:self.serializer_class(queryset, many=True)
2. Спасибо, я полный идиот. Я проверял свой сериализатор в течение последнего часа, задаваясь вопросом, что происходит. Спасибо за помощь!