【问题标题】:What is the read/write equivalent of serializers.StringRelatedField?serializers.StringRelatedField 的读/写等价物是什么?
【发布时间】:2015-02-24 06:15:08
【问题描述】:

在 Django Rest Framework 3 中,我想返回 pk 关系的 unicode 值,您可以使用 serializer.StringRelatedField 的方式,但我也需要该值是可写的。 StringRelatedField 是只读的。

我不在乎 API 是否接受 PUT 上的 pk 或字符串值(尽管接受字符串会很漂亮,而且我会省去抓取所有 pk 的麻烦!)。 API 只需要在 GET 上返回 unicode 字符串值。

我认为 PrimaryKeyRelatedField 可能是要走的路,但查询是什么样的?

例如,如果我想要的模型是“模型”,并且我希望 Model.name 被序列化,那么这个命令是什么样的:

name = serializers.PrimaryKeyRelatedField(queryset=Model.objects.get(pk=????))

我很苦恼,因为我不知道如何从序列化器对象中获取 pk 以查询相关模型...

这是假设 PrimaryKeyRelatedField 是我需要的,当然。这可能是完全错误的。

谢谢

约翰

以下是根据要求提供的示例模型,为清楚起见略有改动:

class CarModel(models.Model):
  name = models.CharField(max_length=100,unique=True)

  def __str__(self):
    return self.name


class Car(models.Model):
  name = models.CharField(max_length=100)
  make = models.ForeignKey(CarMake)
  car_model = models.ForeignKey(CarModel)

class CarSerializer(serializers.ModelSerializer):
   car_model = serializers.StringRelatedField() //like this, but read/write

   class Meta:
   model = Car

在此示例中,我正在序列化 Car,试图返回 CarModel 的字符串值,该值可以通过表单中的选择下拉列表进行更新。 如果我使用不同的序列化程序,一个用于期望 PK 的 POST,另一个用于返回字符串的其他所有内容,表单中的 select 指令会变得非常混乱。

因此,理想情况下,我只想能够发布字符串值,并让 API 完成查找并将字符串保存为 PK。

【问题讨论】:

  • 您可以编辑您的问题以包括您的模型吗?
  • 已添加。希望对您有所帮助。

标签: django django-rest-framework


【解决方案1】:

“我只是希望能够 POST 字符串值,并让 API 完成查找并将字符串保存为 PK。”

这意味着“名称”应该是唯一的。如果它不是唯一的,那么查找可能会返回几个实例。在示例中,您当前拥有的 'name' 不是唯一的,但如果是,那么您可以使用...

car_model = serializers.SlugRelatedField(queryset=..., lookup_field='name')

我不相信这是否真的是你想要的。澄清这类问题的最佳方法通常是暂时忘记代码,只专注于精确描述您希望输入和输出表示的样子?...

【讨论】:

  • 是的,抱歉,名称是唯一的。我想在序列化程序中返回 CarModel.name,而不是 CarModel.pk 或 CarModel.slug,因此我可以使用该值来填充选择小部件。我可以使用 StringRelatedField 进行只读操作,但是我无法使用用户选择的 CarModel.name 发布到 API。
  • 为了说明这一点,这是消除嵌套序列化程序的一部分,因为嵌套序列化程序变得混乱。我正在尝试编写一个单一的、整洁的序列化程序,它不嵌套其他序列化程序并使用多个 ReST 动词,并且不需要来自客户端的第二个 GET 来查找 PK 的字符串值。但我是 ReST 的新手,我什至不确定这样的目标是否是最佳实践。也许您应该始终在 API 中返回 PK,并期望客户端执行第二次 db 调用以查找字符串值?
  • @John 通常对于查询集,您只需执行Model.objects.all()。我相信queryset 参数决定了写作(不是阅读)的可能选择。
  • 哦,伙计。如果不是只读的,则需要一个查询集。我认为 Model.objects.all() 会返回整个表格,但我认为你是对的。它只返回查找值。我现在很接近了!
  • 这行得通,正如凯文和汤姆所说:car_model = serializers.SlugRelatedField(queryset=CarModel.objects.all(), slug_field='name')。谢谢大家!
猜你喜欢
  • 2014-05-08
  • 2014-06-12
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 2023-04-10
  • 2011-01-19
相关资源
最近更新 更多