序列化非直接相关的关系

时间:2015-12-31 13:22:14

标签: django serialization django-rest-framework json-api

我有Project,属于艺术家(django User):

class Project:
    artist = models.ForeignKey(User)

我还有ProductProject的一部分:

class Product:
    project = models.ForeignKey(Project)

artistProduct不是直接关系,但可以通过Project找到。在序列化时,我想直接序列化artist中的Product,以便将其视为Product模型的关系之一。我试过定义一个艺术家属性:

class Product(models.Model):
...
    @property
    def artist(self):
        return self.project.artist.id

我的序列化器:

class ProductSerializer(serializers.ModelSerializer):

    class Meta:
        model = Product
        fields = ('id', 'project', 'artist', 'name', 'description', 'compatibility', 'format', 'type', 'created', 'modified', 'price', 'bought', 'image', 'price_range')

但这只是将艺术家身份作为一种属性,而不是一种关系。如果我删除.id

class Product(models.Model):
...
    @property
    def artist(self):
        return self.project.artist

然后它无法序列化:

TypeError: <User: leia-70823> is not JSON serializable

如何序列化这种间接关系?

修改

这是我得到的当前JSONApi,其中艺术家ID错误地放在attributes部分:

{
  "data": {
    "type": "product",
    "id": "101",
    "attributes": {
      "artist": 306,
      "name": "big Product",
      "description": "Veniam modi doloremque ducimus. Sit aut officiis suscipit libero itaque. Animi sit molestiae corrupti sed qui impedit.",
      "compatibility": 10,
      "format": 6,
      "type": 2,
      "created": "2001-10-19",
      "modified": "1981-02-20",
      "price": 861,
      "bought": 3939,
      "image": "http:\/\/localhost:15013\/media\/categories\/l2.png",
      "price-range": 1
    },
    "relationships": {
      "project": {
        "data": {
          "type": "project",
          "id": "185"
        }
      }
    }
  }
}

我希望将它放在relationships部分,就像项目的链接一样。

1 个答案:

答案 0 :(得分:0)

要获取艺术家(django用户)的实际序列化数据,您必须将艺术家字段设为UserSerializer类型

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User

然后,如果您需要artist序列化数据中的Product,请按以下步骤修改产品序列化程序

class ProductSerializer(serializers.ModelSerializer):
    artist = UserSerializer(source='project.artist', read_only=True)
    class Meta:
        model = Product
        fields = ('id', 'project', 'artist', 'name', 'description', 'compatibility', 'format', 'type', 'created', 'modified', 'price', 'bought', 'image', 'price_range')

现在,艺术家键将是artist实例本身的序列化值,而不仅仅是id。希望这有用

此外,我发现您几乎包含Product in Product serializer中的所有字段。你使用的方式有点复杂。有更好的方法来做到这一点。在Meta类中使用excludehttp://www.django-rest-framework.org/api-guide/serializers/#specifying-which-fields-to-include