Django rest framework 如何使用超链接表示与django rest框架的多对多关系

Django rest framework 如何使用超链接表示与django rest框架的多对多关系,django-rest-framework,Django Rest Framework,我有两个“多对多”关系的模型视频和体裁。我想使用Django Rest框架和超链接在API中表示它们。我曾尝试使用在internet上找到的嵌套关系解决方案,但它给列表视图带来了一个错误,如流派/和视频/,如下所述 models.py class VideoGenre(models.Model): video = models.ForeignKey(Video, on_delete=models.CASCADE, related_name='genres') genres = m

我有两个“多对多”关系的模型视频体裁。我想使用Django Rest框架和超链接在API中表示它们。我曾尝试使用在internet上找到的嵌套关系解决方案,但它给列表视图带来了一个错误,如流派/视频/,如下所述

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)
序列化程序.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']
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__"
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()
url.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"),
path('videos/',views.VideoListView.as_view(),name='video-list'),
路径('videos/',views.VideoDetailView.as_view(),name='video-detail'),
路径('genres/',views.GenreListView.as_view(),name=“genre list”),
path('genres/',views.GenreDetailtView.as_view(),name=“genre detail”),
我在可浏览的API渲染器上遇到以下异常

异常类型:编程错误位于/api/genres/ 异常值:关系“ku\u api\u videogenre”不存在 第1行:…_视频。“所有者id”来自“ku_api_视频”内部连接“ku_api_vi…”

我已经查看了上面提到的这些链接

。。。并尝试了它们,但得到了相同/几乎相同的结果,唯一不同的是“不存在”的关系名称


我错过了什么?如何使它正确?谢谢

我找到了一种方法: 更改将在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']
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__"
序列化程序.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']
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__"
资料来源: