Django REST:为OneToOne字段创建CRUD操作



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

我的模型是Django REST中默认的User模型,

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')

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

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',)

应该重点定义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: Retrieve the user profile

  • POST: Create a new user

  • PUT: Change user of password

  • DELETE: Delete user

因此,它将实现user实例的基本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'}})

最新更新