嵌套的获取或创建功能-DRF

时间:2019-08-16 17:48:24

标签: django django-rest-framework

有一些关于嵌套创建功能的文章,但是似乎没有任何帮助。

您可以在这里看到我的json发布请求的样子:

{
  "games": [
    {
      "company": {
        "name": "Google",
        "website": "https://google.com",
        "trustedpilot": "5"
      },
      "genres": [],
      "formats": [],
      "platforms": [],
      "title": "Call of duty modern warfare",
      "cover": "https::cover.jpg",
      "link": "https://google.com",
      "prev_price": "60.00",
      "price": "40.00"
    }
  ],
  "company": {
    "name": "Google",
    "website": "https://google.com",
    "trustedpilot": "5"
  },
  "name": "Bundle name",
  "prev_price": "50.00",
  "price": "20.00"
} 

游戏序列化器在创建单个游戏时似乎可以正常工作:

class GameSerializer(serializers.HyperlinkedModelSerializer):
    company = CompanySerializer(many=False)
    genres = GenreSerializer(many=True)
    formats = FormatSerializer(many=True)
    platforms = PlatformSerializer(many=True)

    class Meta:
        model = Game
        fields = '__all__'

    def create(self, validated_data):
        # Many to one
        company_data = validated_data.pop('company')
        # Many to Many
        genres_data = validated_data.pop('genres')
        formats_data = validated_data.pop('formats')
        platforms_data = validated_data.pop('platforms')

        # Company
        company, created = Company.objects.get_or_create(**company_data)

        # Get the game or created a new one if it doesn't exist yet
        game, created = Game.objects.get_or_create(**validated_data, company=company)

        # Platform
        for platform_data in platforms_data:
            platform, create = Platform.objects.get_or_create(**platform_data)
            game.platforms.add(platform)

        # Format
        for format_data in formats_data:
            format, create = Format.objects.get_or_create(**format_data)
            game.formats.add(format)

        # Genre
        for genre_data in genres_data:
            genre, create = Genre.objects.get_or_create(**genre_data)
            game.genres.add(genre)
        return game

这是当前的捆绑序列化器

class BundleSerializer(serializers.HyperlinkedModelSerializer):
    games = GameSerializer(many=True)
    company = CompanySerializer(many=False)

    class Meta:
        model = Bundle
        fields = '__all__'

    def create(self, validated_data):
        # Many to one
        company_data = validated_data.pop('company')
        # Many to Many
        games_data = validated_data.pop('games')
        # Company
        company, created = Company.objects.get_or_create(**company_data)

        # Bundle
        bundle, created = Bundle.objects.get_or_create(**validated_data, company=company)

        # Games
        for game_data in games_data:
            company2 = game_data.pop('company')
            company3, created = Company.objects.get_or_create(**company2)

            game, created = Game.objects.get_or_create(**game_data, company=company3)
            bundle.games.add(game)

        return bundle

在该地区:游戏(在 BundleSerializer 内部),出现以下错误:

  / bundles / int()参数处的

TypeError必须是字符串,类似于字节   对象或数字,而不是“列表”

这是我已经尝试过的:

for game_data in games_data:
    # first attempt
    game, created = Game.objects.get_or_create(**game_data)
    # second attempt
    company = game_data.pop('company')
    game, created = Game.objects.get_or_create(**game_data, company=company)
    bundle.games.add(game)

错误似乎来自:

game, created = Game.objects.get_or_create(**game_data, company=company)

有什么建议吗? (额外的问题:Game.objects.create是否转到序列化程序的create方法?)

已编辑

网址

router = DefaultRouter()
router.register(r'users', views.UserViewSet, 'user')
router.register(r'games', views.GameViewSet, 'game')
router.register(r'genres', views.GenreViewSet, 'genre')
router.register(r'formats', views.FormatViewSet, 'format')
router.register(r'platforms', views.PlatformViewSet, 'platform')
router.register(r'bundles', views.BundleViewSet, 'bundle')
router.register(r'companies', views.CompanyViewSet, 'company')

urlpatterns = [
    path('', include(router.urls)),
]

观看次数

class GameViewSet(viewsets.ModelViewSet):
    queryset = Game.objects.all()
    serializer_class = GameSerializer

class BundleViewSet(viewsets.ModelViewSet):
    queryset = Bundle.objects.all()
    serializer_class = BundleSerializer

0 个答案:

没有答案