Попытка перенаправить пользователя со страницы бронирования в 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/'))
- не нужно использовать HttpResponseRedirect.
- 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,
},
)