【问题标题】:django rest framework fails to serialize foreignkey field from string valuedjango rest框架无法从字符串值序列化外键字段
【发布时间】:2025-12-27 00:00:07
【问题描述】:

我正在尝试将发布数据提交到 api 端点,该端点应该创建一个模型实例并在响应中返回对象。

这是返回的错误信息。

IntegrityError at /api/messages/
null value in column "sender_id" violates not-null constraint
DETAIL:  Failing row contains (27, null, null, this is a test message, warning: this is a test. this is only a test. please disregard. ..., f, null, f, f).

前两个null 字段应该是发送者和接收者,我认为它们没有被正确序列化。

发布请求正文如下所示。 senderreceiver 是外键字段。

{
    "sender": "user1",
    "receiver": "user2",
    "subject": "this is a test message",
    "body": "warning: this is a test. this is only a test. please disregard. say hello to your mother for me.",
    "read": false,
    "sender_deleted": false,
    "receiver_deleted": false
}

这是我的模型和视图。

class MessageSerializer(serializers.HyperlinkedModelSerializer):
     pk = serializers.IntegerField(read_only=True)
     sender = serializers.StringRelatedField()
     receiver = serializers.StringRelatedField()

     class Meta:
         model = Message
         fields = ['pk', 'sender', 'receiver', 'subject', 'body', 'read', 'sender_deleted', 'receiver_deleted']

 class Message(models.Model):
     sender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='sent_mail')
     receiver= models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='received_mail')
     subject = models.CharField(max_length=50, default='')
     body = models.TextField()
     read = models.BooleanField(default=False)
     sender_deleted = models.BooleanField(default=False)
     receiver_deleted = models.BooleanField(default=False)
     replies = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='parent_message')

     def __str__(self):
         return self.subject

序列化程序无法将提供的用户名与用户对象相关联。我该如何解决这个问题?

【问题讨论】:

  • 来自docs StringRelatedField This field is read only.
  • 谢谢。我将 StringRelatedFields 更改为 SlugRelatedFields,它可以工作。

标签: django django-rest-framework


【解决方案1】:

我将只写的 StringRelatedFields 更改为 SlugRelatedFields。

 class MessageSerializer(serializers.HyperlinkedModelSerializer):
     pk = serializers.IntegerField(read_only=True)
     sender = serializers.SlugRelatedField(slug_field='username', queryset=User.objects.all())
     receiver = serializers.SlugRelatedField(slug_field='username', queryset=User.objects.all())
      class Meta:
         model = Message
         fields = ['pk', 'sender', 'receiver', 'subject', 'body', 'sender_read', 'receiver_read', 'sender_deleted', 'receiver_deleted']

【讨论】: