Попытка перенаправить пользователя со страницы бронирования в django

Это мой первый проект на Django, и я действительно борюсь. Это простое приложение для бронирования, где вошедший в систему пользователь находится на странице с формой для бронирования и списком текущих бронирований. Я могу заставить страницу работать и сделать заказ, но информация в форме не очищается, и если страница обновляется, она делает заказ снова. Чтобы решить эту проблему, я думаю, что мне нужно, чтобы страница была перенаправлена на страницу успеха после бронирования. Когда я пытаюсь это сделать, я получаю ошибку "NoReverseMatch", и мне говорят, что это "не действительная функция представления или имя шаблона."

Вот шаблоны url из booking.urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path("", views.home, name='home'),
    path("booking/", views.booking, name='booking'),
    path('my_bookings/', views.my_bookings, name='my_bookings'),
    path('edit_booking/<int:booking_id>', views.edit_booking, name='edit_booking'),
    path('delete_booking/<int:booking_id>', views.delete_booking, name='delete_booking'),
    path('success_booking/', views.success_booking, name='success_booking'),
]

Вот некоторые части файла booking.views.py:

def my_bookings(request):
    bookings = Booking.objects.filter(user=request.user)
    booking_form = BookingForm()
    if request.method == "POST":
        booking_form = BookingForm(data=request.POST)
        if booking_form.is_valid():
            booking = booking_form.save(commit=False)
            booking.user = request.user
            booking.save()
            return HttpResponseRedirect(reverse('/booking_delete/'))

    return render(
        request, 
        "booking/booking_list.html",
        {
            'booking_form' : booking_form,
            'bookings': bookings,
        },
    )


А вот фрагмент файла booking_list.html, в котором рассматривается кнопка отправки:

<div class="col-md-4 mb-4 mt-3">
          <div>
            {% if user.is_authenticated %}
            <form id="bookingForm" method="post"
              style="margin-top: 1.3em;">
              {{ booking_form | crispy }}
              {% csrf_token %}
              <button id="BookingButton" type="submit"
                class="btn btn-lg btn-light">Make A Booking</button>
                <!-- <a class="btn btn-light btn-edit" href="{% url 'my_bookings' %}">Make Booking</a> -->
            </form>
            {% else %}
            <p>Log in to make a booking</p>
            {% endif %}
          </div>

Я знаю, что мне не хватает понимания того, как все это работает. Я пробовал изменять файл урлов и использовать DTL для кнопки отправки. Я пробовал различные аргументы в функции HttpResponseRedirect(), но я действительно потерялся!!!

Есть 2 проблемы с этой строкой

return HttpResponseRedirect(reverse('/booking_delete/'))
  1. не нужно использовать HttpResponseRedirect.
  2. reverse или reverse_lazy принимают параметр url name для получения url, а не сам url.

Обновите эту строку, код должен работать

from django.urls import reverse
return redirect(reverse('booking_delete'))

Если я правильно вас понял, ваша цель - перенаправить пользователя на другой url при успешном завершении формы, а не обновлять страницу формы еще раз. Прежде всего, ваше использование reverse() не является правильным.

reverse() концепция предназначена для вызова представления по имени, а не по URL.

В вашем случае вы вызываете HttpResponseRedirect(), который принимает URL как строку. Но вы пытаетесь передать метод reverse(), который "преобразует" имя представления в URL под капотом. Другими словами: вы хотите использовать redirect(), но в этом случае нужно передать URL, а не метод reverse(). Но если вы любите, чтобы Django строил URL путь за вас, то reverse() действительно удобен: Как только вы зададите имя представления :

app_name = "booking"
path('delete_booking/<int:booking_id>', views.delete_booking, name='delete_booking')

Вы можете использовать это имя во всем проекте, чтобы избежать жесткого кодирования и сделать дополнительную работу в будущем, так как вам нужно просто изменить URL в urls.py и reverse() метод будет использовать обновленный URL во всем проекте во всех местах, где представление вызывается по имени.

Поэтому вы можете изменить свой код следующим образом, используя reverse():

if booking_form.is_valid():
            booking = booking_form.save(commit=False)
            booking.user = request.user
            booking.save()
            return redirect(reverse('delete_booking'))

Хорошей практикой является использование name представления в шаблонах, а также:

<a href="{% url 'view_name' %}">

Когда ваш проект становится больше, полезно добавить app_name переменную для каждого url.py модуля приложения. Это позволит вам получить доступ к определенному имени представления через app_name.

reverse('app_name:view_name')

То же самое прекрасно работает с шаблонами Django:

<a href="{% url 'app_name:view_name' %}">

В моем представлении отсутствовал идентификатор бронирования:

def my_bookings(request):
bookings = Booking.objects.filter(user=request.user)
booking_form = BookingForm()
if request.method == "POST":
    booking_form = BookingForm(data=request.POST)
    if booking_form.is_valid():
        booking = booking_form.save(commit=False)
        booking.user = request.user
        booking.save()
        print('booking id', booking.id)
        return redirect(reverse('booking:success_booking', args=[booking.id]))

return render(
    request, 
    "booking/booking_list.html",
    {
        'booking_form' : booking_form,
        'bookings': bookings,
    },
)
Вернуться на верх