href link to urls.py
Date: March 20th 2016
Last updated: March 20th 2016
Using text to create a link seems easy enough. The gotcha for me was when the href required an argument to be passed to views.py. The objective of this entry is to link the profile page up to the edit page. In short, if the current page omits a variable from context it is not available for use as an argument in a url statement.
urls.py (app)
The objective is to transition from profile to update. That is, the http path is going from http://127.0.0.1:8080/1/ to http://127.0.0.1:8080/1/update.
app_name = 'surferprofile'
urlpatterns = [ #<snipped>
url(r'^(?P<surfer_id>[0-9]+)/$',views.profilepage, name='profile'),
url(r'^(?P<surfer_id>[0-9]+)/update/$', views.updateprofile, name='update'),]
views.py (update method)
At this point urls.py has received a request (with associated arguments) which then makes a call to the updateprofile method.
def updateprofile(request, surfer_id):
surfer = get_object_or_404(Surfer, pk=surfer_id)
form = SurferForm(request.POST or None, instance=surfer)
if form.is_valid():
form.save()
return redirect('/{}/'.format(surfer_id))
return render(request, 'surferprofile/updateprofile.html', {'form': form})
template.html (profile.html)
When edit is clicked the url request is made to the urlpattern called 'update'. surferprofile:update is written like this because I defined app_name in urls.py. surfer.id is the parameter required to go to updateprofile and entered as surfer_id.
<p>
<a href = "{% url 'surferprofile:update' surfer.id %}"> edit </a>
</p>
Gotcha
This failed not because the syntax is incorrect but because surfer.id was not available to profile.html. Certainly surfer is available and various other attributes. The problem has occured before rendering profile.html.
views.py (profile method)
The profilepage method passed to profile.html is given the alias surfer as seen at the end of return statement. What is getting passed to "surfer" is surfer_profile which holds the surfers name. If I entered surfer.name as an argument in the url statement in template.html I would actually pass an argument. After adding an id field to become available while looking at the profile page I could utilise surfer.id as an argument.
def profilepage(request, surfer_id):
surfer_profile = dict()
surfer = get_object_or_404(Surfer, pk=surfer_id)
# surfer_profile['id'] = surfer_id #<================ THIS WAS MISSING!!!!
surfer_profile['name'] = '{} {}'.format(surfer.firstname, surfer.lastname)
# <snipped>
return render(request, 'surferprofile/profile.html',{'surfer': surfer_profile})