django View

2019-06-03

let's see how to make View and how to use View in django for web pages.

Outline

we’ve done many things to serve a web service - connecting the database to store the data, how to Create Read Update Delete(CRUD) the data, and how to create and connect URL. in this blog post, we’ll see how to make django View for a web page and how to use it.

this blog is a series. if you want to check other blog posts of the series, see the links below.

also, this blog series source code is opened on Github. you can see full source code via the link below.

Review URL

in the previous blog post(django Routing), we’ve seen how to connect URL to HTML. execute the django command to start the test server, and open http://127.0.0.1:8000/ on the browser. we can see Hello World on the web page.

# source venv/bin/activate
# cd django_exercise/
python manage.py runserver

Data Transmission

now we try to transmit the data that we’ve created in the previous blog post(django ORM) to View to show on the web page. open and modify blog/views.py like below.

from django.shortcuts import render
from .models import Post

def posts(request):
    posts = Post.objects.filter(published_at__isnull=False).order_by('-published_at')
    return render(request, 'blog/posts.html', {'posts': posts})
  • from .models import Post: load(import) Post Model
  • posts = Post.objects.filter(published_at__isnull=False).order_by('-published_at')
    • published_at__isnull=False: get the data to query published_at is not null(__isnull=False)
    • order_by('-published_at'): sort the data descending with published_at.
  • return render(request, 'blog/posts.html', {'posts': posts}): transmit the data named posts variable({'posts': posts}) to blog/posts.html page.

Display Data

let’s try to display the data that we transmitted above. open blog/templates/blog/posts.html and modify it like below.


<html>
  <head><title>Hello World</title></head>
  <body>
    {% for post in posts %}
    <div>
      <h1>
        {{ post.title }}<small>(published: {{ post.published_at }})</small>
      </h1>
      <p>{{ post.content | linebreaksbr }}</p>
    </div>
    {% endfor %}
  </body>
</html>

  • {% for post in posts %}...{% endfor %}: make a loop to get a post data from posts data list we created above.
  • {{ post.title }}<small>(published: {{ post.published_at }})</small>: display title / published_at field values in post
  • <p>{{ post.content | linebreaksbr }}</p>: display content field value in post data with changing linebreak(\n) to linebreak tag(<br/>).

after editing, when you open http://127.0.0.1:8000/ on the browser, you can see the data is displayed on the screen like below.

display data in django View

let’s make the detail page for the practice. modify blog/templates/blog/posts.html file we created above like below.


<html>
  <head><title>Hello World</title></head>
  <body>
    {% for post in posts %}
    <a href="{% url 'post_detail' id=post.id %}"> <!-- <<<<<<<<<<<<<<<<<<<<< here -->
      <h1>
        {{ post.title }}<small>(published: {{ post.published_at }})</small>
      </h1>
      <p>{{ post.content | linebreaksbr }}</p>
    </a> <!-- <<<<<<<<<<<<<<<<<<<<< here -->
    {% endfor %}
  </body>
</html>

  • {% url 'post_detail' id=post.id %}: django searches post_detail name in django_exercise/urls.py and blog/urls.py we’ve defined and changes it to URL. at this time, django creates id parameter and input Post id to it.

we don’t make URL mapped post_detail not yet. let’s make post_detail URL and View. create blog/templates/blog/post_detail.html file and modify it like below.


<html>
  <head><title>Hello World</title></head>
  <body>
    <a href="{% url 'posts' %}">
      Post List
    </a>
    <h1>
      {{ post.title }}
    </h1>
    <p>created: {{ post.created_at }}</p>
    <p>updated: {{ post.updated_at }}</p>
    <p>published: {{ post.published_at }}</p>
    <p>author: {{ post.author.username }}</p>
    <p>{{ post.content | linebreaksbr }}</p>
  </body>
</html>

  • {% url 'posts' %}: search posts name of URL and change it to the URL.
  • author: {{ post.author.username }}: we’ve connected our Post Model and auth.User that dajango basically provides to make author field. so we can get and display username from auth.User Model.

the page is ready. open and modify blog/urls.py like below.

from django.urls import path
from . import views

urlpatterns = [
    path('', views.posts, name='posts'),
    path('post/<int:id>/', views.post_detail, name='post_detail'), # <<<<<<<<<<<< here
]
  • post/<int:id>/: make URL with id parameter data that is integer data type.
  • name='post_detail': URL name is post_detail and mapped views.post_detail.

now, we can ready to use {% url 'post_detail' id=post.id %} to show post/<int:id>/ URL and connect views.post_detail. open blog/views.py and modify it like below.

from django.shortcuts import render, get_object_or_404 # <<<<<<<<<<<< here
from .models import Post


def posts(request):
    posts = Post.objects.filter(
        published_at__isnull=False).order_by('-published_at')
    return render(request, 'blog/posts.html', {'posts': posts})

# <<<<<<<<<<<< here
def post_detail(request, id):
    post = get_object_or_404(Post, id=id)
    return render(request, 'blog/post_detail.html', {'post': post})
  • get_object_or_404: load(import) the function that django basically provides. this function tries to get the data from the Object, but if the data doesn’t exist, the function occurs 404 error.
  • def post_detail(request, id):: new function mapped with new URL. the function can get id parameter.

done! we’ve created the detail page. open http://127.0.0.1:8000 on the browser. you can see the screen lik below.

django Models - detail page link

when you click the detail page lik, you’ll go to the detail page URL(http://127.0.0.1:8000/post/2/) and you can see the detail page like below.

django Models - detail page

Templage File

we were used to making new View and URL, and display it. however, there are many duplicated code in HTML. even we didn’t insert css, js or meta tag. if we insert them, duplicate code will be more and more. so let’s see how to make Template that includes common codes and use it.

first, let’s see how to add static files(css, js, etc). create blog/static/css/main.css file and modify it like below.

h1 {
  color: red;
}

in here, we won’t consider the design of the site. if you want to make the site more beautiful, modify this file. django will search the folder named static automatically, so we don’t need any additional action to register it.

now, create blog/templates/blog/layout.html and modify it like below.


{% load static %}
<html>
  <head>
    <title>Hello World</title>
    <link rel="stylesheet" href="{% static 'css/main.css' %}" />
  </head>
  <body>
    {% block content %} {% endblock %}
  </body>
</html>

  • {% load static %}: load(import) static folder to make this file can use static files.
  • <link rel="stylesheet" href="{% static 'css/main.css' %}" />: search css/main.css file in static folder we loaded and change this to the URL.
  • {% block content %} {% endblock %}: make the block named content to display Template. if we make the block like block [name], we can use it on the other Template files and change this to their block.

open and modify blog/templates/blog/posts.html like below to use layout Template file


{% extends 'blog/layout.html' %}

{% block content %}
  {% for post in posts %}
    <a href="{% url 'post_detail' id=post.id %}">
      <h1>
        {{ post.title }}<small>(published: {{ post.published_at }})</small>
      </h1>
      <p>{{ post.content | linebreaksbr }}</p>
    </a>
  {% endfor %}
{% endblock %}

  • {% extends 'blog/layout.html' %}: this file(posts.html) will use the layout file(layout.html) we made.
  • {% block content %}...{% endblock %}: this block contents will insert to the layout file(layout.html) block named content.

and then, open and modify blog/templates/blog/post_detail.html like below.


{% extends 'blog/layout.html' %}

{% block content %}
  {% for post in posts %}
    <a href="{% url 'post_detail' id=post.id %}">
      <h1>
        {{ post.title }}<small>(published: {{ post.published_at }})</small>
      </h1>
      <p>{{ post.content | linebreaksbr }}</p>
    </a>
  {% endfor %}
{% endblock %}

it’s the same as above. search the block named content in the layout file(layout.html) and insert this block to there.

Check

let’s connect http://127.0.0.1:8000/ via the browser. you can see the screen applied css file we made like below.(if you couldn’t see the screen applied css file, try to restart the test server.)

use django Template - main page

click the detail page link to go to the URL(http://127.0.0.1:8000/post/2/). you can see the screen applied css file like below.

use django Template - detail page

done! we’ve seen how to use dajgno Template file to reduce duplicate codes and how to insert static files(css, js, etc) to the Template.

Completed

in this blog post, we’ve seen how to use django View briefly. and we’ve seen how to use django Template to manage the code and display the data in the page. also, we’ve seen how to insert static files like css, js. now we can ready to make normal web service site!

Buy me a coffeeBuy me a coffee
Posts