Сериализация не связанных напрямую отношений

У меня есть Projectпринадлежащий художнику (джанго User):

class Project:
    artist = models.ForeignKey(User)

у меня тоже есть Productчасть Project:

class Product:
    project = models.ForeignKey(Project)

artist не прямые отношения на Product, но можно найти через 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 Я получаю, с идентификатором художника, неправильно помещенным в 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 ответ

Для получения актуальных сериализованных данных об исполнителе (пользователь 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 Сам экземпляр, а не просто идентификатор. Надеюсь, это полезно

Также я вижу, что вы включаете почти все поля Product в Product serializer. способ, которым вы используете, является довольно сложным. есть лучший способ сделать это. использование exclude в классе Мета. http://www.django-rest-framework.org/api-guide/serializers/

Другие вопросы по тегам