Только владелец профиля может обновлять данные

Использование класса Based (APIView) в фреймворке отдыха Django для получения и исправления (обновления) данных UserInfo.

views.py

class getUserInfo(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, format=None):
        user = request.user
        userinfos = user.userinfo_set.all()
        serializer = UserInfoSerializers(userinfos, many=True)
        return Response(serializer.data)

    def patch(self, request, pk, format=None):
        user = UserInfo.objects.get(id=pk)
        serializer = UserInfoSerializers(instance=user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializers.py

from django.contrib.auth.models import User
from .models import UserInfo

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'first_name', 'username')

class UserInfoSerializers(serializers.ModelSerializer):
    user = UserSerializer(many=False, required=True)

    class Meta:
        model = UserInfo
        fields = ('id', 'picture', 'profession', 'user')

Все работает пока хорошо. Можно получить и PATCH (обновить) данные зарегистрированного пользователя. При тестировании API в Postman я обнаружил, что если пользователь User1 вошел в систему, он может изменить данные пользователя User2, используя только pk пользователя User2.

urls.py

urlpatterns = [
    path('userinfo/', views.getUserInfo.as_view(), name="UserInfo"),
    path('userinfo/<str:pk>/', views.getUserInfo.as_view()),
    path('api/token/', views.MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('register/', views.RegisterView.as_view(), name='auth_register'),
]

Использование rest_framework_simplejwt для Auth

models.py


from django.contrib.auth.models import User

class UserInfo(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    picture = models.ImageField(upload_to="profile_pics", null=True)
    profession = models.CharField(max_length=200, null=True)

    def __str__(self):
        return "%s's Profile Picture" % self.user

Любая помощь будет оценена по достоинству

Не используйте первичный ключ для получения пользователя. Вы используете user = request.user для получения пользователя в методе get, используйте тот же механизм и в update. Тогда вошедший пользователь сможет обновить только свою информацию, а не информацию других пользователей, или другим способом вы можете проверить, что user = UserInfo.objects.get(id=pk) совпадает с текущим пользователем request.user. Если нет, вы можете показать исключение.

Для извлечения и обновления объекта можно использовать RetrieveUpdateAPIView

class GetUserInfo(generics.RetrieveUpdateAPIView):
    permission_classes = [IsAuthenticated]
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializers
    
    def get_object(self):
        return self.request.user

Здесь мы получаем объект, он будет вызван из метода get_object. Вместо получения пользователя с помощью PK, мы получаем текущего пользователя.

Вы можете использовать один и тот же url для получения и обновления пользователя, просто измените метод в postman при обращении к api. GET для получения и PATCH для частичного обновления.

path('userinfo/', views.GetUserInfo.as_view(), name="UserInfo"),

Вернуться на верх