【问题标题】:CreateAPIView returns TypeError with st() function, when accessing endpoint via browser通过浏览器访问端点时,CreateAPIView 使用 st() 函数返回 TypeError
【发布时间】:2019-11-11 13:17:27
【问题描述】:

我正在编写基于 Django (2.2.2) 和 Django Rest Framework (3.9.4) 的 API。 目标是创建简单的消息系统。 创建用于创建消息的端点后,我得到 TypeError:

TypeError at /api/v1/message/create/
__str__ returned non-string (type Message)

The 'message_body' in the DB contains PL characteristic characters.

我为我的序列化程序尝试了 serializer.Serializer 和 serializer.ModelSerializer,为视图尝试了 CreateAPIView 和 ListCreateAPIView。 真正有趣的是,列出消息的端点工作得很好。

这几乎是来自我的另一个端点(也是 CreateAPIView)的复制粘贴代码,它按预期工作。

我也在 str(self) 上尝试了一些编码的东西,但猜测不正确。

sample.json:(在浏览器中测试 API 的装置)

{
  "model": "core.message",
  "pk": 1,
  "fields": {
    "chat": 1,
    "message_body": "Wiadomość testowa 1",
    "sender": "user",
    "sent": "2019-05-05T10:20:37+01:00",
    "is_viewed": true
  }
}

models.py:

class Message(models.Model):
    """
    Model representing single message in DB
    """
    chat = models.ForeignKey(
        'Chat',
        on_delete=models.CASCADE,
        unique=False
    )
    message_body = models.TextField(blank=False, null=False)
    sender = models.CharField(max_length=4)
    sent = models.DateTimeField(auto_now_add=True)
    is_viewed = models.BooleanField(default=False)

    def __unicode__(self):
        return self.message_body

    def __str__(self):
        return self.message_body.decode('utf8')

views.py:

from rest_framework import generics, status
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from message.serializers import (
    ListMessageSerializer,
    CreateMessageSerializer
)
from core.models import Message



class CreateMessageView(generics.CreateAPIView):
    """
    Create new message view
    """
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    serializer_class = CreateMessageSerializer

    def perform_create(self, serializer):
        """
        Save data to DB, if valid
        """
        if serializer.is_valid():
            serializer.save()
        else:
            return Response(
                serializer.errors,
                status.HTTP_400_BAD_REQUEST
            )

serializers.py

​​>
from rest_framework import serializers
from core.models import Chat, Message


class CreateMessageSerializer(serializers.ModelSerializer):
    """
    Serializer for creating ne message
    """

    class Meta:
        model = Message
        fields = (
            'id',
            'chat',
            'message_body',
            'sender',
            'sent',
            'is_viewed'
        )
        read_only_field = ('id',)

    def validate(self, attrs):
        """
        Validate request data
        """

        message_body = attrs.get('message_body')
        if not message_body or message_body is None:
            msg = _('Can\'t send empty message!')
            raise serializers.ValidationError(msg, code='authentication')

        return attrs

    def create(self, validated_data):
        """
        Insert Message into DB
        """

        return Message.objects.create(**validated_data)


url.py:

from django.urls import path
from message import views


app_name = 'message'
urlpatterns = [
    path('create/', views.CreateMessageView.as_view(), name='create'),
]


我希望能够在浏览器中打开视图: api/v1/消息/创建/ 并测试手动创建新消息:)

【问题讨论】:

  • 你用的是什么版本的 Python 和 Django?
  • Django 2.2.2、Python 3.7.3、DRF 3.9.4
  • 所以你的 __unicode__ 方法是没有意义的,永远不会被调用。但是你能解释一下为什么在__str__ 方法中调用decode 吗?是什么让你认为 body 字段的内容是字节?
  • 这是一个远射,我有点绝望。 DB中的内容是否应该与错误有关?我刚刚想到一件事。 TypeError 消息告诉 __str__() 返回类型“消息” - 这是我的模型的名称。不定义一个get()和queryset可能有什么关系?
  • 但是没有解码会发生什么?

标签: python django rest frameworks


【解决方案1】:

我删除了 PrimaryKeys 之间的关系: 聊天 - DB 中消息的父级

现在一切正常:)

【讨论】:

    猜你喜欢
    • 2013-06-14
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 2021-10-02
    相关资源
    最近更新 更多