Я использую django и django-paypal для своей системы бронирования отелей, чтобы принимать платежи. У меня проблемы с отправкой первичного ключа из одного представления, имеющего систему app_name, в другое представление в другом приложении, называемом платежами.
Теперь я объясню, что я хочу, чтобы произошло здесь:
- Первичный ключ комнаты извлекается, когда пользователь нажимает на комнату (функция резервирования)
- Пользователь нажимает кнопку «Резерв», при этом вызывается функция подтверждения, которая проверяет, есть ли номер в базе данных бронирования. (подтвердить функцию)
- Вывести пользователю сообщение о том, что комната может быть зарезервирована, и автоматически перенаправить пользователя для перехода к функции процесса.
- Функция процесса использует PayPal, чтобы позволить пользователюзаплатите цену за эту комнату. (функции process_payments)
- Пользователь платит за комнату через PayPal, и все. Счастливые дни !!
Однако у меня возникла проблема с шага3 до шага 4, потому что я получаю эту ошибку:
- Реверс для 'процесса' с аргументами '(' ',)' не найден. Попробован 1 шаблон (ов): ['платежи / (? P [0-9] +) / процесс / $'].
Когда я удаляю pk из параметров функции и URL-адреса, он работает, но я не смогу взимать с пользователя нужную сумму, так как у меня нет первичного ключакомнату они пытаются зарезервировать. Я не понимаю, почему это не работает, так как я смог получить первичный ключ от резервного вида до подтверждающего, чтобы проверить, можно ли зарезервировать комнату.
Вот код:
Резервное представление в системном приложении
def reserve(request, pk = None):
if pk: #Checks if the room has a primary key assigned to it
room = Room.objects.get(pk = pk) #Displays all the information about the room
check_in = request.session['check_in']
check_out = request.session['check_out'] #retrieves the dates that the user has inputed
days = diff_in_days(check_in, check_out) #Calculates the difference between the dates
args = {"room": room, "days": days}
else:
room = request.room
Вот представление подтверждения в системных приложениях
def confirm(request, pk = None):
if request.method == 'POST': #Post request the user is sending information to the server
if pk:
invalid_dates = False
room_id = Room.objects.get(pk = pk) #Retrieves the room
guest_id = request.user #Retrieves the user reserving the room
check_in = request.session['check_in']
check_out = request.session['check_out']
#check wether the dates are valid
#case 1: a room is booked before the check_in date, and checks out after the requested check_in date
case_1 = Reservation.objects.filter(room = room_id, check_in__lte = check_in, check_out__gte = check_in).exists()
# case 2: a room is booked before the requested check_out date and check_out date is after requested check_out date
case_2 = Reservation.objects.filter(room = room_id, check_in__lte = check_out, check_out__gte = check_out).exists()
# case 3: is the reverse of case 1 and case 2
case_3 = Reservation.objects.filter(room = room_id, check_in__gte = check_in, check_out__lte = check_out).exists()
if case_1 or case_2 or case_3: #if the dates clash with other reservation display a message
return render(request, "system/confirm.html", {"errors" : "This room is reserved"})
args = {"room_id" : room_id}
return render(request, "system/success.html") #Send the user to the success page
return render(request, "system/success.html", args)
Вот представление платежей_процесса в приложении платежей
def payment_process(request, pk = None):
if request.method == 'POST':
if pk:
room = Room.objects.get(pk = pk)
host = request.get_host()
paypal_dict = {
'business': settings.PAYPAL_RECEIVER_EMAIL,
'amount': room.price,
'item_name': room.name,
'Invoice': 'Test Payment Invoice',
'currency_code': 'GBP',
'notify_url': 'http://{}{}'.format(host, reverse('paypal-ipn')),
'return_url': 'http://{}{}'.format(host, reverse('done')),
'cancel_return': 'http://{}{}'.format(host, reverse('canceled')),
}
form = PayPalPaymentsForm(initial = paypal_dict)
return render(request, 'payments/process.html', {'form': form})
Вот HTML-код:
reserve.html
<form method="POST" name="confirm" action = "{% url 'system:confirm' room.id %}">
{% csrf_token %}
<h1>{{room.name}}</h1>
<p style="visibility: hidden;">{{room.id}}</p>
<img src="{{room.img.url}}">
<h3 >£{{room.price|mul:days}}</h3>
<h5 >{{room.desc}}</h5>
<button type="submit"> Reserve Room </button>
</form>
Вот файл success.html (что видит пользователь, когда может забронировать комнату)
<body onload="setTimeout(function() { document.Redirect.submit() }, 2000)">
<p>{{room.name}</p>
<form name="Redirect" method="POST" action = "{% url 'payments:process' room_id.id %}">
<h1>Congrats you have successfully reserved a room</h1>
</form>
</body>
urls.py верны, все три представления имеют int: pk в своих URL, поэтому я не думаю, что проблема связана с URL, поэтому я их не показывал.
Спасибона ваше время
вот системы urls.py
app_name = 'system'
urlpatterns = [
path('', views.index, name = 'index'),
path('<int:pk>/reserve/', views.reserve, name = 'reserve'),
path('search/', views.search, name = 'search'),
path('<int:pk>/confirm/', views.confirm, name = 'confirm'),
path('success/', views.success, name = 'success'),
]
вот здесь payment.urls
app_name = 'payments'
urlpatterns = [
path('<int:pk>/process/', views.payment_process, name = 'process'),
path('done/', views.payment_done, name = 'done'),
path('canceled/', views.payment_canceled, name = 'canceled')
]
и controller.urls (который содержит настройки.py)
urlpatterns = [
path('admin/', admin.site.urls),
path("system/", include("system.urls")),
path("accounts/", include("accounts.urls")),
path("payments/", include("payments.urls")),
path("paypal/", include('paypal.standard.ipn.urls'))
]
Просто решил, так что я подумал, что другим было бы полезно узнать, как я это сделал.
После того, как я поэкспериментировал с оболочкой python, я понял, что полученная ошибка не содержит ключевого аргумента, а именно: первичный ключ. Поэтому вместо того, чтобы перейти на html-страницу успеха, я просто перешел к платежам: функция paypal, изменив строку: return render (request, "system / success.html"), чтобы вернуть HttpResponseRedirect (reverse ('payment: process)', kwargs = {' pk ': room_id.id})) и предоставил первичный ключ через kwargs. После изменения того, что я все еще получал ошибки, их было проще отлаживать, я снова использовал оболочку python для решения этой проблемы. В функции payment_process я изменил следующий код: 'return_url': 'http://{}{}'.format(host, reverse (' done ')) на' return_url ':' http://{}{}'.format(host, reverse ('payment: done')) сделать то же самое для URL возвратаа также путем размещения платежей.