Please, I have an AttributeError bug to fix, Please, help me out
I created an address project in my Django project which works fine but I want to the program to avoid users from viewing their billing address and update address page if they have not created an address yet.
This is the views of the code that runs well:
views.py
def register_address(request):
instance = ""
try:
if request.method == "POST":
form = AddressForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
messages.success(request, "You have successfully added a shipping address!")
return redirect('address:billing_address')
except:
pass
return render(request,'address/register_address.html',{'form':form})
def billing_address(request):
address = ""
try:
address = UserAddress.objects.get(user=request.user)
except:
pass
return render(request,'address/billing_address.html',{'form':address})
def update_address(request):
form = UpdateForm()
try:
if request.method == "POST":
form = UpdateForm(request.POST)
if form.is_valid():
address = UserAddress.objects.get(user=request.user)
address.user = request.user
address.country = request.POST.get("country")
address.state = request.POST.get("state")
address.area = request.POST.get("area")
address.city = request.POST.get("city")
address.street_name = request.POST.get("street_name")
address.save()
messages.error(request, "You have successfully updated address.")
return redirect('address:billing_address')
except:
pass
return render(request,'address/update_address.html',{'form':form})
urls.py
urlpatterns = [
path('register_address/',views.register_address,name="register_address"),
path('billing_address/',views.billing_address,name="billing_address"),
path('update_address/',views.update_address,name="update_address"),
]
register_address.html
<h2>Register Adress</h2><br>
<form action="" method="POST" onsubmit="myButton.disabled = true; return true;">
{% csrf_token %}
{{form.as_p}}
<input type="submit" class="btn btn-success" name="myButton" value="Submit">
</form><br><br>
<button class="btn btn-primary" onClick = "window.location= '{% url 'address:bi lling_address'%}';">View Billing Address</button> <button class="btn btn-secondary" onClick = "window.location= '{% url 'address:update_address' %}';">Update Address</button><br><br>
</div>
billing_address.html
<br><h1><center>Billing Address page!</center></h1><br>
<div class="container">
<h2>Username:</h2> {{form.user|capfirst}}<br>
<h2>Address:</h2> {{form.street_name|capfirst}}, {{form.area|capfirst}}, {{form.city|capfirst}}, {{form.state|capfirst}}, {{form.country|capfirst}}<br><br>
<button class="btn btn-success" onClick = "window.location= '{% url 'address:update_address' %}';">Edit me</button><br><br><br>
But here is an extension of the code I want so that users are unable to view their billing address and update address unless they have created address.
views.py
def register_address(request):
instance = ""
user = ""
try:
form = AddressForm()
if request.method == "POST":
form = AddressForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
user = UserAddress.objects.get(user=instance.user)
messages.success(request, "You have successfully added a shipping address!")
return reverse('address:billing_address',args=[user.pk])
try:
user = UserAddress.objects.get(user=request.user)
if user is not None:
return reverse('address:billing_address',args=[user.pk])
except:
pass
except:
pass
return render(request,'address/register_address.html',{'form':form,'pk':user})
def billing_address(request,pk):
user = ""
try:
user = UserAddress.objects.get(pk=pk)
if user is not None:
return user
except AttributeError:
messages.error(request, "Please, create an address before viewing address!")
return redirect('address:register_address')
except:
messages.error(request, "Please, create an address before viewing address!")
return redirect('address:register_address')
return render(request,'address/billing_address.html',{'form':user})
urls.py
urlpatterns = [
path('register_address/',views.register_address,name="register_address"),
path('<int:pk>billing_address/',views.billing_address,name="billing_address"),
path('update_address/',views.update_address,name="update_address"),
]
register_addres.html
<h2>Register Adress</h2><br>
<form action="" method="POST" onsubmit="myButton.disabled = true; return true;">
{% csrf_token %}
{{form.as_p}}
<input type="submit" class="btn btn-success" name="myButton" value="Submit">
</form><br><br>
<button class="btn btn-primary" onClick = "window.location= '{% url 'address:billing_address' pk=user.pk %}';">View Billing Address</button> <button class="btn btn-secondary" onClick = "window.location= '{% url 'address:update_address' %}';">Update Address</button><br><br>
billing_address.html
<div class="container">
<h2>Username:</h2> {{form.user|capfirst}}<br>
<h2>Address:</h2> {{form.street_name|capfirst}}, {{form.area|capfirst}}, {{form.city|capfirst}}, {{form.state|capfirst}}, {{form.country|capfirst}}<br><br>
<button class="btn btn-success" onClick = "window.location= '{% url 'address:update_address' %}';">Edit me</button><br><br><br>
</div>
There are many minor mistakes such as:
The route should be
billing_address/<int:pk>/
not<int:pk>billing_address/
.In
register_address
view,pk
is an empty string in case ofGET
request, so how can you send an empty string tobilling_address
view, if it is current logged in user (Assuming already have relationship with inbuilt User model of Django via ForeignKey, AbstractUser or AbstractBaseUser or anything) so you can just sendrequest.user.id
to thebilling_address
view.
Try to use below code.
urls.py:
urlpatterns = [
path('register_address/',views.register_address,name="register_address"),
path('billing_address/<int:pk>/',views.billing_address,name="billing_address"),
path('update_address/',views.update_address,name="update_address"),
]
register_address.html
<form method="POST" onsubmit="myButton.disabled = true; return true;">
{% csrf_token %}
{{form.as_p}}
<input type="submit" class="btn btn-success" name="myButton" value="Submit">
</form><br><br>
<button class="btn btn-primary" onClick = "window.location= '{% url 'address:billing_address' pk=request.user.id %}';">View Billing Address</button>
A view should always return HttpResponse(…)
[Django-doc] or one of its subclasses but you are returning string from the view i.e. return reverse('address:billing_address',args=[user.pk])
will return string. So return response object instead of string in your view as
from django.urls import reverse
from django.http import HttpResponseRedirect
return HttpResponseRedirect(reverse('address:billing_address', args=[user.pk]))
Change accordingly in other return reverse
also.