Как запретить одному пользователю писать несколько рецензий на один и тот же фильм в djnago?
Чего вы хотите достичь
Я хочу запретить одному пользователю писать несколько рецензий на один и тот же фильм. Я получил информацию о фильме из TMDB, поэтому не знал, как ее изменить и спросил.
Текущий код
def view_movie_detail (request, movie_id):
if not (Movie.objects.filter (id = movie_id)):
Movie (id = movie_id) .save ()
movie = Movie.objects.get (id = movie_id)
if request.method == "POST":
form = Comment_movie_CreateForm (request.POST)
if form.is_valid ():
Comment_movie (
comment = form.cleaned_data ['comment'],
user = request.user,
stars = form.cleaned_data ['stars'],
movie = movie
). Save ()
return redirect ('view_movie_detail', movie_id = movie_id)
else: else:
form = Comment_movie_CreateForm ()
data = requests.get (f "https://api.themoviedb.org/3/movie/{movie_id}?api_key={TMDB_API_KEY}&language=en-US")
recommendations = requests.get (f "https://api.themoviedb.org/3/movie/{movie_id}/recommendations?api_key={TMDB_API_KEY}&language=en-US")
comments = reversed (Comment_movie.objects.filter (movie_id = movie_id))
average = movie.average_stars ()
context = {
"data": data.json (),
"recommendations": recommendations.json (),
"type": "movie",
"comments": comments,
"average": average,
"form": form,
}
return render (request, "Movie / movie_detail.html", context)
class Movie (models.Model):
id = models.CharField (primary_key = True, editable = False,
validators = [alphanumeric], max_length = 9999)
def get_comments (self):
return Comment_movie.objects.filter (movie_id = self.id)
def average_stars (self):
comments = self.get_comments ()
n_comments = comments.count ()
if n_comments:
return sum ([comment.stars for comment in comments]) / n_comments
else: else:
return 0
class Comment_movie (models.Model):
class Meta:
unique_together = ('user','movie',)
comment = models.TextField (max_length = 1000)
stars = models.FloatField (
blank = False,
null = False,
default = 0,
validators = [MinValueValidator (0.0),
MaxValueValidator (10.0)]
)
user = models.ForeignKey (CustomUser, on_delete = models.CASCADE)
movie = models.ForeignKey (Movie, on_delete = models.CASCADE)
created_at = models.DateTimeField (default = datetime.now)
updated_at = models.DateTimeField (auto_now = True)
То, что вы спросили
Как изменить текущий код, чтобы сделать один комментарий для одного фильма? И как добавить обновления и удаления?
Для добавления уникальности в вашу модель с индексами для лучшей производительности вы можете использовать что-то вроде этого
class Comment_movie (models.Model):
comment = models.TextField (max_length = 1000)
stars = models.FloatField (
blank = False,
null = False,
default = 0,
validators = [MinValueValidator (0.0),
MaxValueValidator (10.0)]
)
user = models.ForeignKey (CustomUser, on_delete = models.CASCADE)
movie = models.ForeignKey (Movie, on_delete = models.CASCADE)
created_at = models.DateTimeField (default = datetime.now)
updated_at = models.DateTimeField (auto_now = True)
class Meta:
unique_together = ('user', 'movie')
indexes = [
models.Index(fields=['user', 'movie']),
]
но сначала нужно очистить модель от дубликатов записей, потому что при миграции могут возникнуть ошибки