Django REST框架ManyToMany Serializer

时间:2016-08-27 22:11:59

标签: python json django rest django-rest-framework

我已经搜索了现有的问题/答案,DRF文档,并尝试了多个示例来了解我的目标。

我遇到的问题是ShowtimeSerializer没有填充。

This looked the most promising but I couldn't figure it out

Also tried to use this as a non DRF way of doing it

我解析了一些API来获取这个包含放映时间的电影细节的JSON:

{u'poster_path': u'/bEAoNvtqvO0c2lItNkKlKUqhPuw.jpg', u'production_countries': [{u'iso_3166_1': u'US', u'name': u'United States of America'}], u'revenue': 0, u'overview': u"After moving to a new town, troublemaking teen Jim Stark is supposed to have a clean slate, although being the new kid in town brings its own problems. While searching for some stability, Stark forms a bond with a disturbed classmate, Plato, and falls for local girl Judy. However, Judy is the girlfriend of neighborhood tough, Buzz. When Buzz violently confronts Jim and challenges him to a drag race, the new kid's real troubles begin.", 'youtube': 'Rwh9c_E3dJk', 'is_3d': False, u'video': False, u'id': 221, 'category': u'C', u'genres': [{u'id': 18, u'name': u'Drama'}], u'title': u'Rebel Without a Cause', u'tagline': u'The bad boy from a good family.', u'vote_count': 124, u'homepage': u'', u'belongs_to_collection': None, u'original_language': u'en', u'status': u'Released', u'spoken_languages': [{u'iso_639_1': u'en', u'name': u'English'}], 'tmdb_id': 221, u'imdb_id': u'tt0048545', u'adult': False, u'backdrop_path': u'/aFrfCpEwyyAhIbooDANgWiFzV9R.jpg', u'production_companies': [{u'name': u'Warner Bros.', u'id': 6194}], u'release_date': u'1955-10-27', u'popularity': 0.144839, u'original_title': u'Rebel Without a Cause', u'budget': 1500000, u'vote_average': 7.5, 'showtimes': [[{'showdate': datetime.date(2016, 9, 4)}, {'showtime': '10:00AM'}], [{'showdate': datetime.date(2016, 9, 7)}, {'showtime': '10:00AM'}]], u'runtime': 111}

views.py

from django.shortcuts import render
from django.conf import settings
from datetime import datetime, date, time

import requests

from .forms import SubmitFilm
from .serializer import FilmSerializer, ShowtimeSerializer

def save_film(request):

            ...code to build JSON from API's

            serializer = FilmSerializer(data=json)

            print 'Serializer is valid? {}'.format(serializer.is_valid())
            if serializer.is_valid():
                film = serializer.save()
                return render(request, 'films.html', {'film': film})
    else:
        form = SubmitFilm()

    return render(request, 'index.html', {'form': form})

serializer.py

from rest_framework import serializers
from .models import Film, Showtime

class ShowtimeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Showtime

class FilmSerializer(serializers.ModelSerializer):
    showtimes = ShowtimeSerializer(many=True, read_only=True)

    class Meta:
        model = Film

models.py

from __future__ import unicode_literals

from django.db import models

class Showtime(models.Model):
    showdate = models.DateField()
    showtime = models.TimeField()

class Film(models.Model):
    SERIES = (
        ('F', 'Featured'),
        ('L', 'Late Night Series'),
        ('C', 'Classic Movie Series'),
        ('K', 'Prytania Kids Series'),
    )
    imdb_id = models.CharField(max_length=15)
    tmdb_id = models.IntegerField()
    title = models.CharField(max_length=200)
    overview = models.TextField()
    release_date = models.DateField()
    backdrop_path = models.CharField(max_length=200)
    poster_path = models.CharField(max_length=200)
    runtime = models.IntegerField()
    category = models.CharField(max_length=1, choices=SERIES)
    youtube = models.CharField(max_length=20)
    is_3d = models.BooleanField(default=False)
    tagline = models.CharField(max_length=200)
    vote_average = models.DecimalField(max_digits=4, decimal_places=2)
    showtimes = models.ManyToManyField(Showtime)

    def __str__(self):
        return self.title

1 个答案:

答案 0 :(得分:0)

request.data包含用户 app 信息,其ID为一个数组:

{ "user":[1,2,3], "app":[1,2] }

views.py(或api.py)

class SampleViewSet(APIView):

    def post(self, request):
        serializer = TeamSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializer.py

class TeamSerializer(serializers.ModelSerializer):
    class Meta:
        model = Team
        fields = ['user', 'app']

class AppSerializer(serializers.ModelSerializer):
    class Meta:
        model = App
        fields = ['name', 'description']

models.py

class App(models.Model):
    name = models.CharField(max_length=150, default='')
    description = models.TextField(verbose_name='App Description')

    def __str__(self):
        return f'{self.id} - {self.name}'

class Team(models.Model):
    user = models.ManyToManyField(User)
    app = models.ManyToManyField(App)

    def __str__(self):
        return f'Team ID: {self.id}'

最后,this post解决了我的问题,并且我能够理解如何相应地更新我的结构。