Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Variable Arguments From URLs: Routing and Views

In the previous lesson, you learned how to pull one specific resource out of your database. Now you need to build that code into your views and set up the correct routing so that you’ll be able to see the details page of one of your projects.

In urlpatterns in your projects app, you had an empty path that just went to projects without anything afterwards and then rendered your all_projects view. Now, you need to add a second path:

urlpatterns = [
    path('', views.all_projects),
    path('<int:pk>', views.project_detail)
]

You can use the characters < and > to captures a part of a URL and pass it forward into your app.

Comments & Discussion

eclaudio on Dec. 4, 2019

i love your tutorails!!!

eclaudio on Dec. 4, 2019

I love your tutorials!!!

that last message had terrible grammar.

Martin Breuss RP Team on Dec. 4, 2019

Haha, thanks so much @eclaudio :) Django on tuto-Rails!

hollowde on Jan. 1, 2020

I am getting the error

local variable ‘project’ referenced before assignment and thus my links are not working

hollowde on Jan. 2, 2020

I am getting the error

“local variable ‘project’ referenced before assignment”

when I do the projects/1 or projects/2

thus my links are not working

what would you recommend that I do to correct the error I am seeing

Martin Breuss RP Team on Jan. 2, 2020

My quick guess is that you might have spelled Project in the line:

project = Project.objects.get(pk=pk)

with a lowercase p. Keep in mind that you’re assigning the result of the database call Project.objects.get(pk=pk), which uses the Project class from models.py, to a new variable called project (lowercase!), which you are then using.

If the model-reference to the Project model is accidentally in lowercase, you could get the error you are seeing.

Richard Childers on Jan. 23, 2020

Hi Martin,

I am working through your course. Like it very much. Noticed one thing that caused by a bit of problem. In the video called Variable Arguments From URLs: Routing and Views you show a resolving urls summary with the function project_detail with its return statement as so:

return render(request, "projects/detail.html", **{"projects":project})** 

The highlighted part should be {project.project}). If I use projects, plural I get 404 error. You have it correct earlier in the video.

Great work Enjoying the video.

All the best

Richard

Martin Breuss RP Team on Jan. 24, 2020

@Richard Childers: thanks for noticing and posting this clarification here! 🙌

Indeed, in the summary slide, from 7:18 forward in the video, please note that the last line in views.py should be:

    return render(request, "projects/detail.html", {"project": project})

I’m almost through this course and am trying to modify everything to suit my side-project, which is the create a webpage with the following structure…

Home page - this will just be menu with 3 options to select leading to 3 different pages): 1) Projects -> From this Projects page, could further drill into project detail pages for each respective project. This page will pull my project details from the JIRA application using api. 2) Production Processes -> Would be mostly informational/text at first, but eventually would like to build an interactive calendar application on this page. 3) Modeling Applications -> This page will mostly be informational/text

Given this information, is there any particular way I should structure my django project? For example, do I keep everything under my “Home” app folder, or should I be creating separate “applications” for each of these pages?

And if you have any good information or tutorials on best practices for structuring django projects, please feel free to pass along.

Many thanks!

TC on Feb. 1, 2020

So I just tried creating all pages nested under the Home folder. For example, I had the following pages/structure working:

Home -> Projects -> Project# Details

I then proceeded to link the button between Projects page -> Project # Details page. This also worked (by setting app_name=’project’, as you show in your tutorial).

But now I have a conflict…I cannot also create the link between the different Sections on the Home page to the actual section details. The only way that I can correctly link from Home page, say, to the Projects page is if I change the app_name, but this of course breaks the Project -> Project # Details linkage since there can only be one app_name variable. So, maybe I will just wait to get your feedback on my comments above as I’m clearly not structuring this correctly :)

Martin Breuss RP Team on Feb. 2, 2020

Hi @TC! Nice work on extending the app to fit your personal project. Best way to learn more 🙌.

Project Structure

I would suggest to split the functionality you described into three different apps, instead of putting them all into one home app. That means your Django project will contain three Django apps:

  1. projects
  2. processes
  3. blog

Of course you can use different names, whatever describes the apps best. I chose them from your description, with the assumption that the third one will be mostly technical writing you would do.

That way you keep the different functionality in different apps.

Page Linking

If you follow the suggestion above, you can have separate app_names for each of the apps, and link to the apps e.g. like so:

{% url 'projects:details' %}
{% url 'processes:overview' %}

The two snippets above assume that you have two apps (projects and processes) that both have their app_name defined. Additionally, it requires that the projects app has a details function in the app’s views.py, and the same for an overview function in the other app.

Page Linking With One App

Even without following the suggestion above and sticking with your current app setup, you should be able to link to different view functions when they are in the same namespace. This could look like so:

{% url 'projects:details' %}
{% url 'projects:overview' %}

Note that you need to define separate view functions and also link to them specifically. One of the lines above would resolve to a URL that points to the details function, the other one to the overview function. In this case, both of them are located in the views.py file of the same app–one with the namespace (=app_name) projects.

Does this help to clarify the situation?

TC on Feb. 3, 2020

Ah, perfect! Thanks so much, Martin. I’ll attempt to do it by what seems to be the more correct way and split them into separate apps.

Thanks again!

Hi Martin - just getting some time recently to try your recommendations out. I structured things slightly differently in that I created 4 apps instead of 3:

1. Home - Desc: this app will serve two main purposes: 1) Will show a summary view of my workday and to-do’s, and 2) Will house 3 icons which will link to the 3 apps below.

2. Projects 3. Processes 4. Applications

So, with the “{% url ‘....’ %}” lines you wrote your previous comment, obviously, there are multiple of them now since we need one for each app and its respective namespace. And those lines of code will reside in home->templates->home->html file. Then, it seems I will need to dynamically provide the namespace and function for the given app in this html file?

If so, would you then recommend that I just store the namespace and corresponding function names in the home app database and plug it into the “{% url ‘....’ %}” line of code dynamically usign the for loop you previously showed us how to write? Or is there a different or more proper way I should be doing this?

Trying to do things semi-correctly before I get too far down the road with this app and then realize I have to do a major overhaul.

Martin Breuss RP Team on Feb. 21, 2020

Nice job following the double-folder structure! 👍

home -> templates -> home -> something.html

^ This is the right place to put your HTML files for your Home app. :)

Then, from what I understand, you want to link to the main pages of your other apps from the Home app, right?

Just as you wrote, you will need to include the {% url app_name:name %} as the href attribute for each link that you’re creating.

There’s no need to use a loop for that and I think that would over-complicate things. You already know what are the three pages that you want to link to (= the base pages of your three apps), so you can put in three links with the corresponding URL patterns, like so:

<a href="{% url projects:name_of_your_view_function %}">Projects</a>
<a href="{% url processes:name_of_your_view_function %}">Processes</a>
<a href="{% url applications:name_of_your_view_function %}">Applications</a>

You will need to replace the name_of_your_view_function part with whatever names you gave the main functions of your different apps in the respective urls.py files.

Martin Breuss RP Team on Feb. 21, 2020

Also check out the next video which talks in more detail about URL linking in Django.

ehaglund62 on May 15, 2020

When I runserver to 127.0.0.1:8000/projects/1 I get an error message saying “Invalid block tag on line 8: ‘static’. Did you forget to register or load this tag?”

I’m pretty stuck on this. I’m not sure where, or how far back the error goes.

Martin Breuss RP Team on May 16, 2020

@ehaglund62 Sounds to me like you might have forgotten a piece for setting up your static files correctly. Your template needs two things for that:

  1. Loading the static tag: This happens at the top of each template where you want to reference static files: {% load static %}
  2. Linking the static file: With static loaded, you can then use the static template tag to link to CSS files or images etc.: <img src="{% static 'your/path/image.png' %}">

Check out Django’s helpful docs on Managing static files.

ehaglund62 on May 16, 2020

@Martin Breuss, I can’t believe I missed that! Thanks for the fix.

vivekdeo on May 25, 2020

view:

def project_detail(request,pk):
    project = Project.objects.get(pk=pk)
    print(project)
    return render(request, 'projects/detail.html',
                  {'projects': project})

detial.html:

/head>
<body>
 <h1>Inside detail.html!!</h1>
 {{ project }}
 <p>{{ project.title }}</p>
</body>
</html>

When I run http://127.0.0.1:8000/projects/1 I can see the message Inside ..... on web page , but it nodes not show anything for {{ project }}

print project on server command line shows:

Project object (1)

What am I missing?

Martin Breuss RP Team on May 26, 2020

Hi @vivekdeo you’ve stumbled across a subtle typo: one superfluous "s"!

In your view function you’re passing the data on to your template with the key name projects. This key name is how you will be able to access it in your template. However, in your template you are trying to access the data via the key project (without the s at the end).

So you just need to keep in mind that the key in your context dictionary and the variable name that you use to access the data under in your template match up.

Become a Member to join the conversation.