制作一个 API 将实例添加到 django rest 框架中模型的 ManyToMany 字段

making an API that adds instances to ManyToMany fields of a model in django rest framework

我正在制作一个电影观看网站,其中有用户和电影,用户模型有一个引用电影模型的 ManyToMany 字段。它称为监视列表,经过身份验证的用户可以将他们想要的任何电影添加到此监视列表。

我的问题是我想要一个 API 只获取电影的 ID 并将其添加到用户的观看列表。

这些是我的模型和序列化程序,我正在尝试创建一个视图来实现这个 API。

# models.py
class Film(models.Model):
    filmID = models.AutoField(primary_key=True)
    title = models.CharField(max_length=150)
    # ...

class User(AbstractBaseUser, PermissionsMixin):
    userID = models.AutoField(primary_key=True)
    username = models.CharField(max_length=100, unique=True, validators=[RegexValidator(regex="^(?=[a-z0-9._]{5,20}$)(?!.*[_.]{2})[^_.].*[^_.]$")])
    email= models.EmailField(max_length=100, unique=True,  validators=[EmailValidator()])
    name = models.CharField(max_length=100)

    watchList = models.ManyToManyField(Film)

    objects = UserManager()

    USERNAME_FIELD = 'username'
# serializers.py
class WatchListSerializer(serializers.ModelSerializer):
    class FilmSerializer(serializers.ModelSerializer):
        model = Film
        fields = ('filmID', 'title',)
        read_only_fields = ('filmID', 'title')

    film_set = FilmSerializer(read_only=True, many=True)

    class Meta:
        model = get_user_model()
        fields = ('userID', 'film_set')
        read_only_fields = ('userID',)
# views.py
class WatchListAddView(...):
    pass

可以更改序列化程序。但是这种显示了我想要 api 的样子。身份验证验证部分已经处理完毕,因此假设对视图的任何请求都来自经过身份验证的用户。

我不建议直接修补它,而是创建一个单独的端点来向该字段添加删除数据。

在您的情况下,它看起来像这样。我只是展示了一个小的工作示例,您可以根据需要进行调整

from django.shortcuts import get_object_or_404
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()

    @action(detail=True,
            methods=['POST'])
    def add_film_to_watch_list(self, request, **kwargs):
        film = get_object_or_404(klass=Film, filmID=kwargs.get('filmID'))
        user = self.get_object()
        user.watchList.add(film)
        return Response("Success")