首页 文章

Django REST:为OneToOne Field创建CRUD操作

提问于
浏览
4

我正在尝试为OneToOne字段创建基本的CRUD操作 . 登录时,用户无需设置配置文件 . 如何在需要时创建/更新/删除配置文件(假设用户已在数据库中)?

我的模型是Django REST的默认用户模型,并且:

class UserProfile(models.Model):
        user = models.OneToOneField(User)
        location = models.CharField(max_length=50,blank=True)
        title = models.CharField(max_length=80,blank=True)
        #picture = models.ImageField(upload_to='user_imgs', blank=True)
        website = models.URLField(blank=True)

我的视图集是:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_fields = ['id', 'username', 'email', 'first_name', 'last_name']

class UserProfileViewSet(viewsets.ModelViewSet):
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer
    filter_fields = ['user_id', 'location', 'title', 'website']

并序列化:

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        email = serializers.EmailField()
        fields = ('id','username', 'email', 'first_name', 'last_name')


class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
    user_id = serializers.CharField(source='user.id')

    class Meta:
        model = UserProfile
        fields = ('user_id', 'location','title','website')

2 回答

  • 2

    我相信你想要将配置文件创建限制为当前登录用户 . 您可以将配置文件的查询集过滤到当前用户,这样只有登录用户才能访问该用户的配置文件 .

    class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserSerializer
        filter_fields = ['id', 'username', 'email', 'first_name', 'last_name']
    
    
    class UserProfileViewSet(viewsets.ModelViewSet):
        queryset = UserProfile.objects.all()
        serializer_class = UserProfileSerializer
        filter_fields = ['user_id', 'location', 'title', 'website']
    
        def get_queryset(self):
            return super(UserProfileViewSet, self).get_queryset().filter(
                user=self.request.user)
    
        def perform_create(self, serializer):
            serializer.save(user=user)
    

    您将 user 字段设置为只读并保存在上述方法 perform_create 中,并始终分配给当前用户 .

    class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = UserProfile
            fields = ('user', 'location','title','website')
            read_only_fields = ('user',)
    
  • 3

    它应该集中定义 view 如何接收请求和处理原始数据,而不是字段定义的 modelserializer .

    我给你一个基本 User 操作的CRUD示例作为参考:

    lu = LibraryUser(library_membership_number ='...',user_id = user)

    class ExampleAPIView(APIView):
        def get(self, request):
            username = request.query_params.get('username', '')
            user = User.objects.get(username=username)
            return Response(ExampleSerializer(user).data)
    
        def post(self, request):
            username = request.data.get('username', '')
            email = request.data.get('email', '')
            password = request.data.get('password', '')
            user = User.objects.create_user(username=username, email=email, password=password)
            user.save()
            Response({'status': 'ok'}})
    
        def put(self, request):
            username = request.data.get('username', '')
            old_password = request.data.get('old_password', '')
            new_password = request.data.get('new_password', '')
            user = authenticate(username=username, password=old_password)
            if not user:
                return Response({'status': 'fail'}})
            user.set_password(new_password)
            return Response({'status': 'ok'}})
    
        def delete(self, request):
            username = request.query_params.get('username', '')
            user.objects.get(username=username).delete()
            return Response({'status': 'ok'}})
    

    根据示例,这些是我对每种方法的定义:

    • GET :检索用户 Profiles

    • POST :创建新用户

    • PUT :更改密码的用户

    • DELETE :删除用户

    因此,它将为 user 实例实现Basic CRUD api .

    我希望它可以帮助你如何设计api .


    如果您还不了解如何操作 model ,我将更多介绍该示例:

    class ExampleAPIView(APIView):
        def get(self, request):
            username = request.query_params.get('username', '')
            userprofile = UserProfile.objects.get(user__username=username)
            return Response(ExampleSerializer(userprofile).data)
    
        def put(self, request):
            username = request.data.get('username', '')
            userprofile = UserProfile.objects.get(user__username=username)
            if not userprofile :
                return Response({'status': 'fail'}})
            userprofile.location = ...
            userprofile.title = ...
            userprofile.website = ...
            userprofile.save()
            return Response({'status': 'ok'}})
    

相关问题