Skip to main content

Views And URLs

Writing And Configuring Your First View

Remember that when a request is received, the web server passes it to your Django project to return a response which can be sent to the web browser. That means that when the project receives a request (that is, when a user visits any URL address on your site), a function defined in one of the project's applications is invoked to return a response. That's where you take over control of the site and where you can run Python code. So the first thing we're going to do is create a function inside the myapp/views.py file. Delete the existing code (generated by the startapp command) and write the following:

from django.http import HttpRequest, HttpResponse


def index(request: HttpRequest) -> HttpResponse:
return HttpResponse("Hello, world!")

We are importing some classes from the django.http module. Through the HttpResponse class you can create the response that you want to return to the web browser. The argument given to HttpResponse is a string with the response content. Functions that return instances of HttpResponse are known as views, hence the file name views.py.

Now, you need to tell Django which URL this index() function should respond to. To do this you are going to create the myapps/urls.py file with the following code:

from django.urls import path
from . import views


urlpatterns = [
path("", views.index, name="index")
]

This code may seem a little strange, but it's just the structure that Django has chosen for each application's urls.py file, where URLs and views get bound. Bindings are included as elements of the urlpatterns list. For each of them, using the django.urls.path() function we indicate (following the order of the arguments):

  1. The URL to which a view should respond (in this case, the empty string indicates the home or index page.)
  2. A function that receives a request as argument.
  3. A string that identifies the former function (you will later see why this is useful.)
note

It is common to use relative paths when importing a module while creating Django applications. Remember that your myapp application is a Python package, which Django will import to invoke the views (that is, call the functions) defined in the myapp.views module. By default, the current working directory of a Django application is the path of the project using it (in our case, the myproject folder, where the manage.py file is located.) When you need to import the myapp/views.py module in the myapp/urls.py file, you do not simply do import views, since this would look for the views.py file in the myproject folder. Instead, you do:

from . import views

In this context the dot indicates that the views module is next to the file from which it is being imported; that is, that views.py (the imported file) and urls.py (from which it gets imported) are in the same location (myproject/myapp). An alternative way to import the views would be the following:

from myapp import views

Or:

import myapp.views as views

This is not an unusual syntax, but it has the problem that if the myapp package is renamed, you must update all the lines where it is imported.

So far, you have configured URLs for your myapp application. Now, you need to add this particular configuration to the general configuration of the project (remember that a project can have multiple applications.) To do this, open the myproject/urls.py file (which is not the same as myapp/urls.py!) and replace its contents with the following:

from django.urls import path, include


urlpatterns = [
path("myapp/", include("myapp.urls"))
]

With this code you are telling Django: in my project, I want all URLs starting with myapp/ (for example, http://127.0.0.1:8000/myapp/ or http://domain.com/myapp/) to be routed to the myapp application. Whatever follows that URL (for example, /contact or /about-us) will be managed by that application's URL settings, that is, by the myapp/urls.py file you created earlier. Since in this file you have defined that the index() view should respond to an empty string, when visiting http://127.0.0.1:8000/myapp/ you will see the content of the response that you returned in that function.

Django Hello World

Including A Second View

Let's do this procedure one more time to clarify it a little. Aadd the following view to your application in the myapp/views.py file:

def about_us(request: HttpRequest) -> HttpResponse:
return HttpResponse("Python and Django Tutorial!")

Now associate it with a URL, say, /about-us by adding an elemento to the urlpatterns list in myapp/urls.py:

urlpatterns = [
path("", views.index, name="index"),
path("about-us", views.about_us, name="about_us")
]

Finally, visit http://127.0.0.1:8000/myapp/about-us and you will see:

A Second View In Django

Note that the URLs defined for an application are relative to the configuration they have received in the project in which it is included. The myapp/ prefix was defined by the project in the myproject/urls.py file, while about-us was defined in the application, hence the final URL address is http://127.0.0.1:8000/myapp/about-us.

If a project contains only one application, you can remove the prefix by defining an empty string in myproject/urls.py:

urlpatterns = [
path("", include("myapp.urls"))
]

If this were the case, the URL for the myapp.views.about_us() view would be http://127.0.0.1:8000/about-us.