这里我想加入这两个表,我希望一旦用户登录,他/她就可以对一部电影进行评分,而只有一个用户可以对该电影进行评分。如果同一用户试图再次对其进行评分,那么它应该显示错误消息
我已经使用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将负责连接表并过滤结果