序列化程序中的外键读取为 HyperlikedModelSerializer 但仅使用 id 写入
Foreign key in serializer read as HyperlikedModelSerializer but written only with id
我有一个 Django 模型,它有一个与用户相关的字段作为外键。
class Notification(models.Model):
sender = models.ForeignKey(User, null=True)
is_read = models.BooleanField(default=False)
我希望我的序列化程序显示此模型的用户 ID 和名称,因此它是这样的:
{
"count": 45,
"next": null,
"previous": null,
"results": [
{
"id": 2,
"sender": {
"id": 2,
"name": "my_name",
}
"is_read": false,
}
]
}
但是当我添加新通知时,我只想发送用户的 ID,如下所示:
$ curl -X POST http://127.0.0.1:8000/notifications/ -H "Content-Type: application/json" -d "{\"sender\":\"4\"}"
我尝试在我的序列化程序中使用超链接:
class NotificationSenderSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('id', 'name')
class NotificationSerializer(serializers.ModelSerializer):
sender_name = serializers.NotificationSenderSerializer()
class Meta:
model = Notification
fields = ('id', 'sender', 'is_read')
但结果是,这样,我需要在发布新通知时同时发送用户 ID 和用户名。
$ curl -X POST http://127.0.0.1:8000/notifications/ -H "Content-Type: application/json" -d "{\"sender\": {\"id\": \"4\", \"name\":\"my_name\"} }"
如何解决这个问题,以便我可以创建仅包含用户 ID 的通知,但在读取通知列表时会同时收到 ID 和名称?
我通过同时发送 id 和 obj,但将 obj 设置为只读来解决这个问题:
class NotificationSerializer(serializers.ModelSerializer):
sender_obj = serializers.NotificationSenderSerializer(
source="sender", read_only=True, required=False)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class Meta:
model = Notification
fields = ('id', 'sender', 'sender_obj', 'is_read')
# ^^^^^^ ^^^^^^^^^^
这样,您就可以访问发件人 ID 并可以写入,但您也可以访问发件人对象本身。您将必须在客户端手动保持这些同步。根据 required=False
,您不必在 post 结果时发送发件人对象,因为它也是 read_only
,对该对象的所有更新都将是 被服务器忽略。
您还可以将 sender
字段设置为只写,这样它就不会从服务器发送:
sender = serializers.IntegerField(
required=False,
write_only=True, # <---
allow_none=True,
blank=True)
我仍在使用 DRF 2.4.4,因此您可能需要针对 DRF 3.+
调整上述语法
我有一个 Django 模型,它有一个与用户相关的字段作为外键。
class Notification(models.Model):
sender = models.ForeignKey(User, null=True)
is_read = models.BooleanField(default=False)
我希望我的序列化程序显示此模型的用户 ID 和名称,因此它是这样的:
{
"count": 45,
"next": null,
"previous": null,
"results": [
{
"id": 2,
"sender": {
"id": 2,
"name": "my_name",
}
"is_read": false,
}
]
}
但是当我添加新通知时,我只想发送用户的 ID,如下所示:
$ curl -X POST http://127.0.0.1:8000/notifications/ -H "Content-Type: application/json" -d "{\"sender\":\"4\"}"
我尝试在我的序列化程序中使用超链接:
class NotificationSenderSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('id', 'name')
class NotificationSerializer(serializers.ModelSerializer):
sender_name = serializers.NotificationSenderSerializer()
class Meta:
model = Notification
fields = ('id', 'sender', 'is_read')
但结果是,这样,我需要在发布新通知时同时发送用户 ID 和用户名。
$ curl -X POST http://127.0.0.1:8000/notifications/ -H "Content-Type: application/json" -d "{\"sender\": {\"id\": \"4\", \"name\":\"my_name\"} }"
如何解决这个问题,以便我可以创建仅包含用户 ID 的通知,但在读取通知列表时会同时收到 ID 和名称?
我通过同时发送 id 和 obj,但将 obj 设置为只读来解决这个问题:
class NotificationSerializer(serializers.ModelSerializer):
sender_obj = serializers.NotificationSenderSerializer(
source="sender", read_only=True, required=False)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class Meta:
model = Notification
fields = ('id', 'sender', 'sender_obj', 'is_read')
# ^^^^^^ ^^^^^^^^^^
这样,您就可以访问发件人 ID 并可以写入,但您也可以访问发件人对象本身。您将必须在客户端手动保持这些同步。根据 required=False
,您不必在 post 结果时发送发件人对象,因为它也是 read_only
,对该对象的所有更新都将是 被服务器忽略。
您还可以将 sender
字段设置为只写,这样它就不会从服务器发送:
sender = serializers.IntegerField(
required=False,
write_only=True, # <---
allow_none=True,
blank=True)
我仍在使用 DRF 2.4.4,因此您可能需要针对 DRF 3.+
调整上述语法