I want to add review function in movie_detail.html
, but I don't know how to query comments and map to movie_detail
.It returns Reverse for 'add_review' with arguments '('',)' not found error.
My url.py:
urlpatterns = [
path('', MovieList.as_view(), name='movie_list'),
path('<int:pk>', MovieDetail.as_view(), name='movie_detail'),
path('search/', MovieSearch.as_view(), name='movie_search'),
path('addreview/<int:id>/', views.add_review, name='add_review'),
]
My model.py:
class Movie(models.Model):
title = models.CharField(max_length=200)
actors = models.CharField(max_length=500, null=True)
poster_url = models.CharField(max_length=200)
director = models.CharField(max_length=200, default='')
score = models.FloatField()
genres = models.CharField(max_length=200)
language = models.CharField(max_length=200, default='English')
durations = models.IntegerField(default=0)
regions = models.CharField(max_length=200, default='')
release_date = models.DateField(default=timezone.now)
description = models.TextField(max_length=1000, default='')
year = models.IntegerField(default=2000)
views_count = models.IntegerField(default=0)
created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
def genres_as_list(self):
genre_list = self.genres.split('/')
return genre_list
def actors_as_list(self):
return self.actors.split('/')
class Review(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
comments = models.TextField(max_length=1000)
rating = models.FloatField(default=0)
data_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
my view.py:
class MovieDetail(DetailView):
model = Movie
template_name = "main/movie_detail.html"
def get_object(self):
object = super().get_object()
object.views_count = 1
object.save()
return object
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['links'] = MovieLinks.objects.filter(movie=self.get_object())
context['related_movies'] = Movie.objects.filter(genres__in=self.get_object().genres_as_list()).order_by(
'created')[0:6]
# context['reviews'] = Review.objects.filter(id=self.kwargs['pk'])
return context
class MovieSearch(ListView):
model = Movie
paginate_by = 20
template_name = "main/movie_list.html"
def get_queryset(self):
query = self.request.GET.get('query')
if query:
object_list = self.model.objects.filter(title__icontains=query)
else:
object_list = self.model.objects.none()
return object_list
@login_required
def add_review(request, id):
movie = Movie.objects.get(id=id)
if request.method != "POST":
form = ReviewForm(request.POST or None)
if form.is_valid():
data = form.save(commit=False)
data.comment = request.POST["comment"]
data.rating = request.POST["rating"]
data.user_id = request.user.pk
data.movie_id = movie.pk
data.save()
return redirect("main:movie_detail", id)
else:
form = ReviewForm()
context = {"form": form}
return render(request, 'main/movie_detail.html', context)
my movies_detail.html
review part:
<section >
<h3>Comment</h3>
<div >
<div >
<h3 >Add Review</h3>
<form method="POST" action="{% url 'main:add_review' movie.id%}">
{% csrf_token %}
<label for="comment">Review</label>
<textarea name="comment" id="comment" cols="30" rows="5" ></textarea>
<label for="rating">Rating</label>
<input type="text" name="rating" >
<br>
<input type="submit" value="Add Review">
</form>
</div>
</div>
I want add the review function and I code the add_review
in view.py by some tutorial.But I don't know how to fix it.
CodePudding user response:
You are not passing the movie object to template, so movie.id
evaluates to an empty to string, which causes the exception you are seeing.
Try this:
@login_required
def add_review(request, id):
movie = Movie.objects.get(id=id)
...
context = {"form": form, "movie": movie}
return render(request, 'main/movie_detail.html', context)
Edit: alternatively, you can just set action=""
as shah sawood pointed out in his answer.
On a side note: Welcome to Stack Overflow! Next time, please post the full stacktrace, that increases your chances of getting an answer to your problem :)
CodePudding user response:
Note
- When you want to post data a view that it renders you need not to specify action but rather leave as
action=""
CodePudding user response:
You're getting the error because you're not passing a movie to the context in the last 2 lines of add_review. You need to update it to
context = {"form": form, "movie": movie}
return render(request, 'main/movie_detail.html', context)