Как я могу реализовать обновление и удаление в представлении django?
Я создаю сайт для просмотра фильмов. В нем я хочу иметь возможность позволить пользователю сделать один комментарий к одному фильму, а затем обновить или удалить этот комментарий. Но сейчас я могу реализовать только POST. Как мне изменить представление, html или модель?
Вопросы, которые нужно задать
- Как мне сделать так, чтобы комментарии были видны, чтобы если один пользователь комментирует один фильм, я не мог его комментировать?
- Как мне сохранить комментарии, размещенные пользователем, в верхней части списка комментариев, чтобы их можно было обновлять и удалять?
Примером того, что мы хотели бы реализовать, является Rotten Tomatoes.
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']),
]
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:
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)
<h2>Comments</h2>
{% if form.errors %}
<div class = "error_list">
{% for errors in form.errors.values %}
{% for error in errors %}
{{ error }}<br>
{% endfor %}
{% endfor %}
</div>
{% endif %}
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<button type="submit">Post Comment</button>
</form>
{% endif %}
<hr>
Похоже, что вы хотите выполнять несколько действий в одном представлении. Одна форма для каждого действия и поле шаблона для разграничения действий было бы решением.
def view_movie_detail(request, movie_id):
…
if request.method == ‘POST’:
if request.POST.get(‘action’) == ‘create’:
# create form
elif request.POST.get(‘action’) == ‘update’:
# update form
elif request.POST.get(‘action’) == ‘delete’:
# delete comment
# instantiate missing forms if form validate to false, or request method is GET
if ‘create_form’ not in locals():
create_form = Comment_movie_CreateForm()
# You may want to make some changes to this conditional logic,
# as update_form is not required when there is no comment at all
if ‘update_form’ not in locals():
update_form = Comment_movie_UpdateForm()
# Same as above
if ‘delete_form’ not in locals():
delete_form = Comment_movie_DeleteForm()
# don’t forget to include these forms to context
…
В шаблонах отобразите все три формы и добавьте 'action' к каждой форме. Одним из хороших мест будет кнопка отправки.
<button type=‘submit’ name=‘action’ value=‘create’>Post Comment</button>
<button type=‘submit’ name=‘action’ value=‘update’>Edit Comment</button>
<button type=‘submit’ name=‘action’ value=‘delete’>Delete Comment</button>
Посмотрите django-multi-form-view. Этот модуль не совсем подходит к вашему вопросу, но разделяет некоторые основные идеи.