PrimaryKeyRelatedField

时间:2016-10-10 10:36:59

标签: python json django serialization django-rest-framework

关于Django DRF版本3.4.7中的PrimaryKeyRelatedField序列化的问题。

模型

class UserModel(AbstractEmailUser):

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.email)
class Conversation(models.Model):
    admin = models.ForeignKey('UserModel', db_index=True, related_name='admin_user')
    patient = models.ForeignKey('UserModel', db_index=True)

    subject = models.CharField(max_length=255, db_index=True)

    user_reply = models.BooleanField(default=False)
    admin_seen = models.BooleanField(default=False)

    expire = models.DateTimeField()

    conversation_type = models.ForeignKey('ConversationType', db_index=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.admin)


class ConversationMessages(models.Model):

    text = models.TextField(db_index=True)

    conversation = models.ForeignKey('Conversation', db_index=True, related_name='msg_conv')
    user = models.ForeignKey('UserModel', db_index=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.user)


class ConversationFiles(models.Model):
    message = models.ForeignKey('ConversationMessages', db_index=True, related_name='message')
    file = models.FileField(upload_to='conversations', db_index=True)

    def __str__(self):
        return str(self.user)

每个模型都有Rest Framework的相关字段。 逻辑是创建对话,然后从对话中获取ID并保存消息模型。

序列' S

class MessagesSerializer(serializers.ModelSerializer):
    text = serializers.CharField(required=False)
    conversation = serializers.PrimaryKeyRelatedField(queryset=Conversation.objects.all(), required=False)
    user = serializers.PrimaryKeyRelatedField(queryset=UserModel.objects.all(), required=False)

    class Meta:
        model = ConversationMessages



class ConversationSerializer(serializers.ModelSerializer):

    admin = serializers.PrimaryKeyRelatedField(queryset=UserModel.objects.all(), required=False)
    msg_conv = MessagesSerializer()

    class Meta:
        model = Conversation

    def create(self, validated_data):
        msg_conv = validated_data.pop('msg_conv', None)
        admin_user = Conversation.objects.create(**validated_data)
        ConversationMessages.objects.create(conversation_id=Conversation.objects.get(id=admin_user.id).id, **msg_conv)

        return admin_user

序列化程序是POST方法的问题。一切都很好POST对象在数据库中创建数据,但问题是当序列化程序保存对象时,我收到此消息:' RelatedManager'对象没有属性'对话'

查看

class ConversationView(APIView):

    authentication_classes = (JSONWebTokenAuthentication,)

    @parser_classes((FormParser, MultiPartParser, FileUploadParser))
    def post(self, request):
        admin = request.user.id
        data = request.data

        my_time = datetime.datetime.strptime('07/05/15', '%m/%d/%y')
        my_time = my_time.replace(hour=23, minute=59)

        data['admin'] = admin
        data['expire'] = my_time

        data['msg_conv']['user'] = admin

        serializer = ConversationSerializer(data=data)

        if serializer.is_valid():
            serializer.save()

            return Response(data={'success': True, 'user': serializer.data}, status=status.HTTP_200_OK)
        else:
            return Response(data={'success': False, 'msg': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

POST json

{

        "subject":"aloha",
        "conversation_type":1,
        "patient":3,

    "msg_conv":{
        "text":"ovo je neki teks"
    }
}

无法弄清楚如何将数据从序列化返回到视图。

Django版本:1.10.2 Python:3.4.3

1 个答案:

答案 0 :(得分:1)

问题在于:

class ConversationSerializer(serializers.ModelSerializer):

    msg_conv = MessagesSerializer()

通过这样做,您说Conversation的FK为Message。因此DRF尝试进行映射并失败,因为它是oposit。

你只需要添加many=True参数让DRF知道这是一个反向的FK。