Python/Django маршрутизация путается при нажатии на кнопку

Я работаю над базовым учебником по django и застрял. Когда нажимается кнопка "избранное", я пытаюсь перенаправить пользователя на страницу reviews/favorite, которая затем перенаправит его на reviews/review_id, с которой он и начал. Вместо этого, всякий раз, когда я нажимаю кнопку избранного на странице, она перенаправляет меня на reviews/reviews/review_id, что не удается.

Интересно, что если я удалю часть /reviews/ из действия формы в файле single-review.html, то он направляет меня на /favorite, что не удается, потому что он не существует, но когда я возвращаю его обратно к reviews/favorite, я возвращаюсь к reviews/reviews/favorite в качестве маршрутизации. Кто-нибудь знает, что я делаю неправильно?

Views.py

from django.http.response import HttpResponse
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django import forms
from django.views import View
from django.views.generic.base import TemplateView
from django.views.generic import ListView
from django.views.generic.detail import DetailView
from django.views.generic.edit import FormView, CreateView

from .forms import ReviewForm
from .models import Review

# Create your views here.

# uses createview to handle all the data processing and then save data to database. Removes need for class ReviewForm in forms.py unless you want to customize
class ReviewView(CreateView):
    model = Review
    form_class = ReviewForm
    template_name = "reviews/review.html"
    success_url = "/thank-you"

class ThankYouView(TemplateView):
    template_name = "reviews/thank_you.html"

    # method allows you to set items to the context dictionary and them import that data into the thank-you.html file via the message variable
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["message"] = "This Works!"
        return context

class ReviewsListView(ListView):
    template_name = "reviews/review-list.html"
    model = Review  # do not instantiate when pointing to model
    context_object_name = "reviews"

class SingleReviewView(DetailView):
    template_name = "reviews/single-review.html"
    model = Review


class AddFavoriteView(View):
    def post(self, request):
        print(request)
        review_id = request.POST["review_id"]
        request.session["favorite_review"] = review_id
        return HttpResponseRedirect("reviews/" + review_id)

Models.py

from django.db import models

# Create your models here.

class Review(models.Model):
    user_name=models.CharField(max_length=100)
    review_text=models.TextField()
    rating = models.IntegerField()

Forms.py

from .models import Review

class ReviewForm(forms.ModelForm):
    class Meta:
        model = Review
        fields = "__all__"
        labels = {
            "user_name": "Your Name",
            "review_text": "Your Feedback",
            "rating": "Your Rating"
        }
        error_messages = {
            "user_name": {
              "required": "Your name must not be empty!",
              "max_length": "Please enter a shorter name!"
            }
        }

Urls.py in /reviews

from django.urls import path

from . import views

urlpatterns = [
    path("", views.ReviewView.as_view()),
    path("thank-you", views.ThankYouView.as_view()),
    path("reviews", views.ReviewsListView.as_view()),
    path("reviews/favorite", views.AddFavoriteView.as_view()),
    path("reviews/<int:pk>", views.SingleReviewView.as_view()),

Urls.py в папке проекта

from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("reviews.urls")),
    path("profiles/", include("profiles.urls"))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Settings.py

Одиночный отзыв HTML страница

{% extends "reviews/base.html" %}

{% block title %}Review Detail{% endblock %}

{% block content %}
    <h1>{{ review.user_name }}</h1>
    <p>Rating: {{ review.rating }} </p>
    <p>{{ review.review_text }}</p>

    <form action='/reviews/favorite' method='POST'>
        {% csrf_token %}
        <input type="hidden" name="review_id" value="{{ review.id }}" />
        <button>Favorite</button>
    </form>
{% endblock %}

В ответе на перенаправление HTTP следует использовать ведущую косую черту:

class AddFavoriteView(View):
    def post(self, request):
        print(request)
        review_id = request.session['favorite_review'] = request.POST['review_id']
        return HttpResponseRedirect(f'/reviews/{review_id}')

Если вы дадите пути имя, например:

path('reviews/<int:pk>', views.SingleReviewView.as_view(), name='review-details'),

тогда вы можете использовать redirect(…) [Django-doc] для определения URL и возвращения правильного ответа HTTP перенаправления:

from django.shortcuts import redirect

class AddFavoriteView(View):
    def post(self, request):
        print(request)
        review_id = request.session['favorite_review'] = request.POST['review_id']
        return redirect('review-details', pk=review_id)
Вернуться на верх