I am pretending to work for a bank. I am writing a Django web app which processes bank account applications from web visitors. It accepts the new client’s first name, last name, and year of their birth. I’m using Django’s Forms API, Form fields, and Model Form Functions. When they submit their application input, Django is supposed to redirect to an ‘Application is Approved’ page displaying the visitor’s personal details that they just entered, including a 4 digit debit card number along with an automatically generated and random routing number and account number, among other details.
It partially works.
The major issue I am tackling now is that views.py
refers to the pk
(primary key) of a specific entry. It’s hard coded. It’s not dynamic. For example, there are 6 people (entries) stored in my db. When the approved.html
template is served, the entry rendered is always the same person (entry) designated in as primary key 3. I would rather have my app pull the entry dynamically, so that Django serves the ‘approved’ page based on the application the web vistor just submitted.
Here is my views.py:
def new_application(request):
# POST REQUEST -- > CONTENTS --> APPROVED
if request.method == "POST":
form = BankAccountApplicationForm(request.POST)
# VALIDATE ROUTINE::
if form.is_valid():
print(form.cleaned_data)
form.save()
return redirect(reverse('account_application_form:approved'))
# ELSE, Re-RENDER FORM
else:
form = BankAccountApplicationForm
return render(request, 'new_application/welcome.html', context={'form':form})
def approved(request):
approved_user = models.User.objects.get(pk=3)
return render(request, 'new_application/approved.html', context= {'approved_user':approved_user})
The second last line at the bottom of that views.py
indicates pk=3
which is why Django keeps serving the 3rd entry. To resolve this issue, I tried adding pk
as arguments to both view functions. No dice. For the validation routine for the redirect function reversal, I also tried combinations of these:
return redirect(reverse('account_application_form:approved/'+str(models.User.objects.filter(id=pk).primary_key)))
Above I tried swapping the order: from id=pk
to pk=id
. Didn’t work.
Next I tried:
return redirect(reverse('account_application_form:approved/'+str(object.pk)))
And:
return redirect(reverse('account_application_form:approved/'+str(models.User.objects.filter('application_approval_date')).pk))
This too:
return redirect(reverse('account_application_form:approved/'+str(models.User.objects.get(pk=pk))))
Every one of the above produced different tracebacks. I am stabbing in the dark at this point.
The original application form works. It accepts user input and stores it. But how do I have Django process a web visitor’s input and then redirect them to the next approved application page?
Here is my urls.py:
from django.http.response import HttpResponse
from django.urls import path, include
from . import views
app_name = 'account_application_form'
urlpatterns = [
path('hello/', views.new_application, name='new_application'),
path('approved/', views.approved, name='approved'),
Above I tried adding <int:pk>/
after 'approved/'
. I tried this in combination with the other various changes to views.py mentioned above.
To help me along with all those different possibilities, I’ve been using Google search terms such as:
- ‘pk primary key django’
- ‘pass in pk to path urls.py’
- ‘specifying primary key in django pk’
- ‘how to refer to primary key django’
- ‘django redirect with primary key urls.py’
- ‘get pk django’
In my searches I’ve encountered all kinds of official and unofficial Django documentation along with Stack Overflow questions and answers. But I can’t figure it out. The gnashing of the teeth!
For reference, here are some more elements to my code base. Here is forms.py:
from django import forms
from .models import User
from django.forms import ModelForm
class BankAccountApplicationForm(ModelForm):
class Meta:
model = User
fields = ['first_name', 'last_name', 'year_of_birth',]
models.py:
from django.db import models
import random
import datetime
from django.utils.timezone import now
class User(models.Model):
# pk
# Next : Dynamic input from prospective clients :
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
year_of_birth = models.CharField(max_length=4,default='1900')
# Unique data generated for each new client after approval :
application_approval_date = models.DateField(auto_now_add=False, default=now)
unique_card_num = models.CharField(max_length=4, default='6054')
routing_num = models.CharField(max_length=5, default=str(random.randint(10000, 99999)))
account_num = models.CharField(max_length=7, default=str(random.randint(1000000, 9999999)))
def __str__(self):
return f'Client {self.first_name} {self.last_name}'
Template: welcome.html:
<body>
<div class="container">
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit Application">
</form>
</div>
</body>
Template: approved.html:
<h1>Your application was approved. Welcome Aboard!</h1>
<h3>Here are your banking details:</h3>
<ul>
<li>pk: {{approved_user.pk}}</li>
<li>First Name: {{approved_user.first_name}}</li>
<li>Last Name: {{approved_user.last_name}}</li>
<li>YOB: {{approved_user.year_of_birth}}</li>
<li>Client Since (Application Approved On): {{approved_user.application_approval_date}}</li>
<li>Assigned Access Card Number (4 Digits): {{approved_user.unique_card_num}}</li>
<li>Assigned Routing Number: {{approved_user.routing_num}}</li>
<li>Assigned Bank Account Number {{approved_user.account_num}}</li>
</ul>