【问题标题】:How to update a many to many field in DRF如何更新 DRF 中的多对多字段
【发布时间】:2022-08-10 09:04:23
【问题描述】:

所以在我的项目中,我有一个用户模型和一个学校模型。我的用户模型有一个 schools 字段,该字段与 School 模型具有 M2M 关系。现在我想知道的是,如何创建一个可以获取用户电子邮件和学校 ID 的视图,并从 user 所属的学校中添加或删除学校。

这是我的user model

class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=255, unique=True, db_index=True)
    email = models.EmailField(max_length=255, unique=True, db_index=True)
    is_verified = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now_add=True)
    schools = models.ManyToManyField(\"School\", related_name=\"members\")

    USERNAME_FIELD = \'email\'
    REQUIRED_FIELDS = [\'username\']

    objects = UserManager()

    def __str__(self):
        return self.email

    def tokens(self):
        refresh = RefreshToken.for_user(self)
        return {
            \'refresh\': str(refresh),
            \'access\': str(refresh.access_token)
        }

学校:

class School(models.Model):
    name = models.CharField(max_length=300, verbose_name=\'school name\', )
    principal = models.ForeignKey(\"User\", related_name=\"my_schools\", on_delete=CASCADE)
    address = models.CharField(max_length=200)

    class Type(models.IntegerChoices):
        PUBLIC = 1, \"Public\"
        PRIVATE = 2, \"Private\"

    type = models.PositiveSmallIntegerField(choices=Type.choices, default=Type.PUBLIC)

    class Level(models.IntegerChoices):
        NATIONAL = 1, \"National\"
        EXTRACOUNTY = 2, \"Extra County\"
        COUNTY = 3, \"County\"
        SUBCOUNTY = 4, \"Subcounty\"

    level = models.PositiveSmallIntegerField(choices=Level.choices, default=Level.COUNTY)

    def __str__(self):
        return self.name

这是注册成员的序列化程序:

class EnrollSchoolMembersSerializer():
    class Meta:
        model = User
        field = (\'email\')

    标签: python django django-models django-rest-framework django-serializer


    【解决方案1】:

    我认为您可以使用函数 API 视图来实现它。首先,您可以定义序列化程序。

    from rest_framework import serializers as sz
    
    class SchoolUpdateSerializer(sz.Serializer):
        school_id = sz.IntegerField()
        email = sz.EmailField()
        mode = sz.CharField()      # can be either 'add' or 'delete'
    

    在views.py 中,您可以编写处理程序。

    from rest_framework.response import Response
    from rest_framework status
    from rest_framework.decorators import api_view, permission_classes
    from .models import School, User
    from .serializers import SchoolUpdateSerializer
    
    @api_view(['POST'])
    @permission_classes([permissions.AllowAny])
    def update_school_data(request):
        serializer = SchoolUpdateSerializer(data = request.data)
        if serializer.is_valid():
            input_data = serializer.validated_data
            email = input_data.get('email')
            mode = input_data.get('mode')
            school_id = input_data.get('school_id')
            try:
                user = User.objects.get(email = email)
                school = School.objects.get(pk = school_id)
                if mode == "add":
                    user.schools.add(school)
                else:
                    user.schools.remove(school)
                return Response(status = status.HTTP_200_OK)       
            except (User.DoesNotExist, School.DoesNotExist):
                return Response(status = status.HTTP_400_BAD_REQUEST)
        else:
            return Response(status = status.HTTP_400_BAD_REQUEST)
            
    

    最后,在前端,您可以使用 POST API。有效载荷可以是

    {
        "email": "test@example.com",
        "school_id": 1,
        "mode": "add"
    }
    

    【讨论】:

    • 你能给我看看 urls.py 和 serializers.py 文件吗?还有错误?
    【解决方案2】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多