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" name="myButton" value="Submit">
</form><br><br>
<button onClick = "window.location= '{% url 'address:bi lling_address'%}';">View Billing Address</button> <button 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 >
<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 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" name="myButton" value="Submit">
</form><br><br>
<button onClick = "window.location= '{% url 'address:billing_address' pk=user.pk %}';">View Billing Address</button> <button onClick = "window.location= '{% url 'address:update_address' %}';">Update Address</button><br><br>
billing_address.html
<div >
<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 onClick = "window.location= '{% url 'address:update_address' %}';">Edit me</button><br><br><br>
</div>
Error
AttributeError at /address/register_address/
'str' object has no attribute 'get'
Request Method: POST
Request URL: http://127.0.0.1:8000/address/register_address/
Django Version: 4.0.4
Exception Type: AttributeError
Exception Value:
'str' object has no attribute 'get'
Exception Location: C:\Users\USER\AppData\Local\Programs\Python\Python310\lib\site-packages\django\middleware\clickjacking.py, line 27, in process_response
Python Executable: C:\Users\USER\AppData\Local\Programs\Python\Python310\python.exe
Python Version: 3.10.0
Python Path:
['C:\\Users\\USER\\Documents\\ADi meals mobile\\my_site',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python310\\python310.zip',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python310\\DLLs',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python310\\lib',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python310',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages']
Server time: Thu, 02 Feb 2023 09:17:24 0000
CodePudding user response:
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.
CodePudding user response:
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" name="myButton" value="Submit">
</form><br><br>
<button onClick = "window.location= '{% url 'address:billing_address' pk=request.user.id %}';">View Billing Address</button>