Как запретить одному пользователю писать несколько рецензий на один и тот же фильм в 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']),
    ]

но сначала нужно очистить модель от дубликатов записей, потому что при миграции могут возникнуть ошибки

Вернуться на верх