Home > OS >  Django: Reverse for 'add_review' with arguments '('',)' not found. 1 p
Django: Reverse for 'add_review' with arguments '('',)' not found. 1 p

Time:03-31

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)
  • Related