我正在尝试编写一个客户权限类,为用户添加权限,以便为每个用户对电影进行一次评分 [英] i am tring to write a customr permissions class to add permissions for the user to rate the movie once per user

查看:60
本文介绍了我正在尝试编写一个客户权限类,为用户添加权限,以便为每个用户对电影进行一次评分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里我尝试添加自定义权限1.用户可以对电影进行一次评分2.用户可以添加电影,创建者以外的其他人可以对其评分.

here i am trying to add custom permissions 1.user can rate the movie once 2.Users can add a movie and other people, except the creator, can rate it.

我已经在permission.py中编写了自定义权限类,但仍然无法满足我的要求但这是错误的.可以请一些帮助

i have written the custom permission class in the permission.py but still it not doing what i want but it is going wrong .can please some help one

models.py

models.py

from django.contrib.auth.models import User
from django.core.validators import MinValueValidator, MaxValueValidator


class Movie(models.Model):
    title = models.CharField(max_length=128)
    director = models.CharField(max_length=128)
    added_by = models.ForeignKey(User, related_name="movie", on_delete=models.CASCADE, null=True)
    added_at = models.DateTimeField(auto_now_add=True)

    # rating=models.IntegerField()
    class Meta:
        db_table = "Movie"

class Rating(models.Model):
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
    rating = models.IntegerField(validators=[MinValueValidator(0),MaxValueValidator(5)])
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_rating')

    class Meta:
        db_table = "Rating"

views.py

from rest_framework.response import Response
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAuthenticated

from knox.models import AuthToken

from TestApp.models import Movie, Rating
from TestApp.serializer import UserSerializer, RegisterSerializer, LoginSerializer, MovieSerializer, RatingSerializer
from TestApp.permissions import *


class UserAPIView(generics.RetrieveAPIView):
    permission_classes = [
        permissions.IsAuthenticated,
    ]
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user


class RegisterAPIView(generics.GenericAPIView):
    serializer_class = RegisterSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })


class LoginAPIView(generics.GenericAPIView):
    serializer_class = LoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })


class MovieAPIView(generics.ListCreateAPIView):
    serializer_class = MovieSerializer

    def get_queryset(self):
        return Movie.objects.all()

    @permission_classes([IsAuthenticated])
    def perform_create(self, serializer):
        serializer.save(added_by=self.request.user)



class RatingAPIView(generics.CreateAPIView):
    serializer_class = RatingSerializer

    @permission_classes([IsAuthenticated,UserPermission])
    def perform_create(self, serializer):

        serializer.save(user=self.request.user)

serializers.py

serializers.py

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

from rest_framework import serializers

from TestApp.models import Movie, Rating
from urllib import request


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


class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'password')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User.objects.create_user(validated_data['username'], validated_data['email'], validated_data['password'])
        return user


class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, data):
        user = authenticate(**data)
        if user and user.is_active:
            return user
        raise serializers.ValidationError("Wrong Credentials")


class MovieSerializer(serializers.ModelSerializer):
    class Meta:
        model = Movie
        fields = ['id', 'title', 'director']


class RatingSerializer(serializers.ModelSerializer):

    # id=MovieSerializer(read_only=True)


    class Meta:
        model = Rating
        fields = ['id', 'movie','rating','user']

permissions.py

permissions.py

from TestApp.models import *

class UserPermission(BasePermission):
    message = 'Adding ratings by same user not allowed.'

    def has_permission(self, request, view,attrs):
        allowed_methods = ['POST', 'PATCH']
        #validated_data = super().validate(attrs)
        user = self.context['request'].user
        if request.method in SAFE_METHODS and Rating.objects.filter(movie=validated_data['movie'], user=user).exists():
            return True
        else:
            return False




class Add(BasePermission):
    def has_permission(self, request, view):
        allowed_methods = ['POST', 'PATCH']
        user = Movie.objects.get(id=user_id)
        t = Rating.objects.filter(added_by_id=user)
        if request.method in allowed_methods:
            if t == user:
                return False
            else:
                return True
        else:
            return True

推荐答案

def has_permission(self, request, view,attrs):
    allowed_methods = ['POST', 'PATCH']
    #validated_data = super().validate(attrs)
    user = self.context['request'].user
    ratings = Rating.objects.filter(movie=validated_data['movie'], user=user)
    if validated_data['movie'].added_by == user:
        return False
    elif request.method in SAFE_METHODS and not ratings.exists():
        return True
    else:
        return False

如果您不想让用户进行两次评分,则用户 not Rating.objects.filter().exists(),即如果对象不存在,则返回True

If you dont want to allow user to rate twice then user not Rating.objects.filter().exists() i.e if object doesn’t not exists then return True

这篇关于我正在尝试编写一个客户权限类,为用户添加权限,以便为每个用户对电影进行一次评分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆