Как представить отношения многие ко многим с django каркасом отдыха, используя гиперссылки - PullRequest
0 голосов
/ 12 марта 2020

У меня есть две модели в отношениях «многие ко многим» Видео и Жанр . Я хочу представить их в своем API, используя Django Rest Framework и с гиперссылками. Я попытался использовать решение для вложенных отношений, которое я нашел через inte rnet, но оно приводит меня к ошибке для просмотра списка, например genres / и videos / , как описано ниже .

models.py

class VideoGenre(models.Model):
    video = models.ForeignKey(Video, on_delete=models.CASCADE, related_name='genres')
    genres = models.ForeignKey(Genre, on_delete=models.CASCADE, related_name='videos')

    class Meta:
        unique_together = ['video', 'genre']

class Video(models.Model):
    genres = models.ManyToManyField(Genre, related_name="videos", blank=True, through='VideoGenre')
    title = serializers.CharField(default=serializers.CurrentUserDefault())

class Genre(models.Model):
name = models.CharField(max_length=20)
descr = models.CharField(max_length=255)

serializers.py

class GenreSerializer(serializers.HyperlinkedModelSerializer):

    videos = serializers.HyperlinkedIdentityField(many=True, view_name="video-detail")

    class Meta:
        model = ku_api_models.Genre
        fields = "__all__"

class VideoSerializer(serializers.HyperlinkedModelSerializer):
    genres = GenreSerializer(source='genre_set', many=True, read_only=True)

    class Meta:
        model = ku_api_models.Video
        fields = "__all__"

class VideoGenreSerializer(serializers.HyperlinkedModelSerializer):
    video = serializers.ReadOnlyField(source='video.id')
    genre = serializers.ReadOnlyField(source='genre.id')

    class Meta:
        model = ku_api_models.VideoGenre
        fields = "__all__"
        unique_together = ['video', 'genre']

views.py

class VideoDetailView(RetrieveUpdateDestroyAPIView):
    parser_classes = (MultiPartParser,)
    serializer_class = VideoSerializer
    queryset = Video.objects.all()

    def perform_update(self, serializer):
        serializer.save(owner=self.request.user)

class VideoListView(ListCreateAPIView):
    parser_classes = (MultiPartParser,)
    serializer_class = VideoSerializer
    queryset = Video.objects.all()

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

class GenreListView(ListCreateAPIView):
    serializer_class = GenreSerializer
    queryset = Genre.objects.all()

class GenreDetailtView(RetrieveUpdateDestroyAPIView):
    serializer_class = GenreSerializer
    queryset = Genre.objects.all()

urls.py

path('videos/', views.VideoListView.as_view(), name='video-list'),
path('videos/<int:pk>', views.VideoDetailView.as_view(), name='video-detail'),
path('genres/', views.GenreListView.as_view(), name="genre-list"),
path('genres/<int:pk>', views.GenreDetailtView.as_view(), name="genre-detail"),

Я получаю исключение ниже для просматриваемого API-интерфейса для визуализации

Тип исключения: ProgrammingError в / api / genres / Значение исключения: отношение "ku_api_videogenre" не существует ЛИНИЯ 1: ... _video "." owner_id "FROM" ku_api_video "INNER JOIN" ku_api_vi ...

Я посмотрел на эти ссылки ниже, как указано выше django остальные рамки сериализации много ко многим полям

взаимосвязь "многие ко многим" через промежуточную модель

сериализация много ко многим полям

... и попытка их, но получая то же самое / почти то же самое, только другое имя отношения, которое "не существует "

Чего мне не хватает? Как сделать это правильно? Спасибо

1 Ответ

0 голосов
/ 19 марта 2020

Я нашел способ для этого: изменения будут в serializers.py

serializers.py

class VideoSerializer(serializers.HyperlinkedModelSerializer):
    genres = serializers.HyperlinkedRelatedField(many=True, read_only=False, view_name='genre-detail', queryset=ku_api_models.Genre.objects.all())


    class Meta:
        model = ku_api_models.Video
        #fields = ('url', 'id', 'datetime_added', 'title', 'video_file', 'owner')
        fields = "__all__"

    def create(self, validated_data):
        genres = validated_data.pop('genres', [])
        video_instance = ku_api_models.Video.objects.create(**validated_data)
        video_instance.genres.set(genres)
        return video_instance

    def update(self, instance, validated_data):
        genres = validated_data.pop('genres', [])
        instance.genres.set(genres)
        instance.save()
        return instance

class VideoGenreSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = ku_api_models.VideoGenre
        fields = "__all__"

class GenreSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = ku_api_models.Genre
        fields = "__all__"

Источник: Документы: посреднические-многиетоманы

...