使用Django Rest框架时出现嵌套序列化器问题。

huangapple go评论66阅读模式
英文:

Issue using nested serializer with django-rest-framework

问题

以下是您要翻译的内容:

"I'm trying to create a nested serializer, UserLoginSerializer, composed of a UserSerializer and a NotificationSerializer, but I'm getting this error when it tries to serialize:

AttributeError: Got AttributeError when attempting to get a value for
field email on serializer UserSerializer. The serializer field
might be named incorrectly and not match any attribute or key on the
UserSerializer instance. Original exception text was:
'UserSerializer' object has no attribute 'email'.

Here is my models.py:

class Notification(models.Model):
    kind = models.IntegerField(default=0)
    message = models.CharField(max_length=256)

class User(AbstractUser):
    username = models.CharField(max_length=150, blank=True, null=True)
    email = models EmailField(unique=True)
    customer_id = models.UUIDField(default=uuid.uuid4, editable=False)

And my serializers.py:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = [
            "id",
            "first_name",
            "last_name",
            "email",
            "customer_id"
        ]

class NotificationSerializer(serializers.ModelSerializer):

    class Meta:
        model = Notification
        fields = [
            "id",
            "kind",
            "message",
        ]

class UserLoginSerializer(serializers.Serializer):
    user_info = UserSerializer(read-only=True)
    notifications = NotificationSerializer(many=True, read-only=True)

The error occurs at the last line in this endpoint:

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": UserSerializer(request.user),
            "notifications": NotificationSerializer(notifications, many=True),
        }
    )
    return Response(serializer.data)

What am I doing wrong?"

请注意,我已经省略了代码部分,只提供翻译。如果您需要进一步的帮助或有其他问题,请随时提问。

英文:

I'm trying to create a nested serializer, UserLoginSerializer , composed of a UserSerializer and a NotificationSerializer, but I'm getting this error when it tries to serialize:

> AttributeError: Got AttributeError when attempting to get a value for
> field email on serializer UserSerializer. The serializer field
> might be named incorrectly and not match any attribute or key on the
> UserSerializer instance. Original exception text was:
> 'UserSerializer' object has no attribute 'email'.

Here is my models.py:

class Notification(models.Model):
    kind = models.IntegerField(default=0)
    message = models.CharField(max_length=256)

class User(AbstractUser):
    username = models.CharField(max_length=150, blank=True, null=True)
    email = models.EmailField(unique=True)
    customer_id = models.UUIDField(default=uuid.uuid4, editable=False)

And my serializers.py:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = [
            "id",
            "first_name",
            "last_name",
            "email",
            "customer_id"
        ]

class NotificationSerializer(serializers.ModelSerializer):

    class Meta:
        model = Notification
        fields = [
            "id",
            "kind",
            "message",
        ]

class UserLoginSerializer(serializers.Serializer):
    user_info = UserSerializer(read_only=True)
    notifications = NotificationSerializer(many=True, read_only=True)

The error occurs at the last line in this endpoint:

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": UserSerializer(request.user),
            "notifications": NotificationSerializer(notifications, many=True),
        }
    )
    return Response(serializer.data)

What am I doing wrong?

答案1

得分: 0

你可以使用 .data 属性。

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": UserSerializer(request.user).data,
            "notifications": NotificationSerializer(notifications, many=True).data,
        }
    )
    return Response(serializer.data)

你必须传递数据,而不是序列化对象本身。data 参数允许你传递一个数据字典,该字典将被内部序列化器用来创建数据的序列化表示。在这种情况下,你将传递来自 UserSerializerNotificationSerializer 的序列化数据给 UserLoginSerializer,然后返回数据的最终序列化表示。

或者,你可以直接传递用户和通知,如下所示:

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": request.user,
            "notifications": notifications
        }
    )
    return Response(serializer.data)

Django Rest Framework 模型序列化器具有一个 to_representation 方法,该方法将模型实例转换为它们的字典表示,因此在这种情况下,UserLoginSerializer 将自动使用 UserSerializerNotificationSerializer 来序列化用户和通知数据。你可以通过重写这个方法来修改/更改其行为。

希望这有所帮助。

英文:

You can use .data attribute.

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": UserSerializer(request.user).data,
            "notifications": NotificationSerializer(notifications, many=True).data,
        }
    )
    return Response(serializer.data)

You must pass the data, not the serializer objects themselves. The data argument allows you to pass in a dictionary of data that will be used by the inner serializers to create a serialized representation. In this case, you will pass in the serialized data from the UserSerializer and NotificationSerializer to the UserLoginSerializer, which then returns the final serialized representation of the data.

Or, you may pass user and notifications directly as such:

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": request.user,
            "notifications": notifications
        }
    )
    return Response(serializer.data)

Django Rest Framework model serializers have a to_representation method which converts the model instances to their dictionary representation, so in this case, the UserLoginSerializer will automatically use the UserSerializer and NotificationSerializer to serialize the user and notifications data. You can modify/change this method's behaviour by overriding it.

I hope this helps.

huangapple
  • 本文由 发表于 2023年2月10日 12:13:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定