In this tutorial we will cover the django views, templates and urls.
from django.shortcuts import render
def index(request):
return render(request, "index.html")
Write this in views.py this is a function and it return a template called index.html
We need to define our urls to map this views.
Let's create a urls.py file
in your main urls.py file add this :
from django.contrib import admin
from django.urls import path, include # add this
urlpatterns = [
path('admin/', admin.site.urls),
path("", include("contact.urls")) # add this
]
Now our application looks like this :
├── contact
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py #new
│ └── views.py
├── db.sqlite3
├── manage.py
├── phonebook
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── Pipfile
└── Pipfile.lock
In contact folder go to urls.py and put :
from django.urls import path
from .views import index
urlpatterns = [
path("", index, name="home")
]
Open your browser and referech the page, what you see ?
You see an error like this TemplateDoesNotExist at /
To solve this add this code in your settings.py
ROOT_URLCONF = 'phonebook.urls'
TEMPLATE_DIR = os.path.join(BASE_DIR, "templates") # add this
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATE_DIR], # add this
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Now we've this structure :
├── contact
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── db.sqlite3
├── manage.py
├── phonebook
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── Pipfile
├── Pipfile.lock
└── templates # new
└── index.html # new
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Home page</title>
</head>
<body>
<h2>Home page</h2>
</body>
</html>
Display the list of contacts
open views.py and put :
from django.shortcuts import render
from .models import Contact # add this
def index(request):
return render(request, "index.html")
# add this
def contact_list(request):
contacts = Contact.objects.all()
return render(request, "contact_list.html", {"contacts": contacts})
and in urls.py
from django.urls import path
from .views import index, contact_list # add this
urlpatterns = [
path("", index, name="home"),
path("contacts/", contact_list, name="contacts") # add this
]
In our template contact_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Contacts</title>
</head>
<body>
<h2>Contacts</h2>
<!-- Check if we've contacts -->
{% if contacts %}
<!-- iterate over contact -->
{% for contact in contacts %}
<p>
{{ contact.first_name }}
</p>
{% endfor %}
{% else %}
<p>No contact</p>
{% endif %}
</body>
</html>
What ?
Why you repeat your self ?
Do you know DRY concept ?
in order to not repeat our self we need to create a base template :
in /templates create a file and call it base.html
I use Bootstrap starter template
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<!-- Bootstrap CSS -->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous"
/>
<title>Phonebook!</title>
</head>
<body>
<h2 class="text-center">
{% block page_title %}
{% endblock %}
</h2>
<div class="container">
{% block content %}
{% endblock %}
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script
src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"
></script>
</body>
</html>
Change the index.html and contact_list.html
{% extends 'base.html' %}
{% block page_title %}
Home page
{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
Home page
</div>
</div>
{% endblock %}
{% extends 'base.html' %}
{% block page_title %}
Contacts
{% endblock %}
<!-- Check if we've contacts -->
{% if contacts %}
<!-- iterate over contact -->
{% for contact in contacts %}
<p>
{{ contact.first_name }}
</p>
{% endfor %}
{% else %}
<p>No contact</p>
{% endif %}
Read more about Django template syntax here!
See you in the next tutorial
Top comments (0)