我正在尝试编写一个客户权限类,为用户添加权限,以便为每个用户对电影进行一次评分 [英] i am tring to write a customr permissions class to add permissions for the user to rate the movie once per user
问题描述
在这里我尝试添加自定义权限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屋!