please, I have an AttributeError bug to fix, Please, help me out

Question:

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.get(user=request.user)
                    messages.success(request, "You have successfully added a shipping address!")
                    return redirect(reverse('address:billing_address',args=[user.pk]))
        except:
            pass
        
        return render(request,'address/register_address.html',{'form':form,'pk':user.pk})
    
    
    
    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=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>

Answers:

There are many minor mistakes such as:

  1. The route should be billing_address/<int:pk>/ not <int:pk>billing_address/.

  2. In register_address view, pk is an empty string in case of GET request, so how can you send an empty string to billing_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 send request.user.id to the billing_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>
Answered By: Sunderam Dubey

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.

Answered By: user8193706
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.