Джанго: Как передать первичный ключ из одного представления в другое? - PullRequest
0 голосов
/ 30 октября 2019

Я использую django и django-paypal для своей системы бронирования отелей, чтобы принимать платежи. У меня проблемы с отправкой первичного ключа из одного представления, имеющего систему app_name, в другое представление в другом приложении, называемом платежами.

Теперь я объясню, что я хочу, чтобы произошло здесь:

  1. Первичный ключ комнаты извлекается, когда пользователь нажимает на комнату (функция резервирования)
  2. Пользователь нажимает кнопку «Резерв», при этом вызывается функция подтверждения, которая проверяет, есть ли номер в базе данных бронирования. (подтвердить функцию)
  3. Вывести пользователю сообщение о том, что комната может быть зарезервирована, и автоматически перенаправить пользователя для перехода к функции процесса.
  4. Функция процесса использует PayPal, чтобы позволить пользователюзаплатите цену за эту комнату. (функции process_payments)
  5. Пользователь платит за комнату через 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 возвратаа также путем размещения платежей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...