![](/img/trans.png)
[英]Can I link Django permissions to a model class instead of User instances?
[英]i am tring to write a customr permissions class to add permissions for the user to rate the movie once per user
在這里我嘗試添加自定義權限 1.用戶可以對電影進行一次評分 2.用戶可以添加電影,除創作者之外的其他人可以對其進行評分。
我在permission.py中寫了自定義權限class,但它仍然沒有做我想要的,但它出錯了。可以請一些幫助
模型.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"
視圖.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)
序列化程序.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']
權限.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()
即如果 object 不存在則返回 True
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.