在这里,用户登录后,他可以对电影进行评分,并且只能对其进行一次评分



这里我想加入这两个表,我希望一旦用户登录,他/她就可以对一部电影进行评分,而只有一个用户可以对该电影进行评分。如果同一用户试图再次对其进行评分,那么它应该显示错误消息

我已经使用knox进行第三方身份验证,我想加入电影和评级表

型号.py

from django.db import models
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="movies", 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):
movies=models.CharField(max_length=128)
rating = models.IntegerField(validators=[MinValueValidator(0),
MaxValueValidator(5)])
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 django.shortcuts import render

# , RegisterSerializer, LoginSerializer, MovieSerializer

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.ListCreateAPIView):
serializer_class = RatingSerializer

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

"""def create(self,serializer):
return Rating.objects.all()
user=self.request.user
if not user:
return ("Please Authenticate Yourself")
else:

return  Response(Rating.objects.all().prefetch_related('movies'))"""

serializers.py

from django.contrib.auth.models import User
from rest_framework import serializers
from TestApp.models import Movie, Rating

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','movies', 'rating']

请帮助如何执行两个表的联接,以及我如何实现一次用户只有一次审核

提前感谢

在评级模型中,您必须将ForeignKey添加到User模型中。此外,你需要将你的电影字段作为ForeignKey,将其链接到电影模型

型号.py

class Rating(models.Model):
movies=models.ForeignKey(Movies, 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"

现在,在你的序列化程序的验证方法中,你可以验证用户是否已经对电影进行了评级

series.py

class RatingSerializer(serializers.ModelSerializer):

def validate(self, attrs):
validated_data = super().validate(attrs)
user =  self.context['request'].user
if Ratings.objects.filter(movies=validated_data['movies'],user=user).exists():
raise serializers.ValidationError('User already rated the movie')
return validated_data
class Meta:
model = Rating
fields = ['id','movies', 'user', 'rating']

然后要获得一部电影的平均评分,你可以进行

from django.db.models import Avg
Ratings.objects.filter(movies__name='movie_name').aggregrate(Avg('rating'))

Django将负责连接表并过滤结果

最新更新