Create django project and display static content

We ll be working with Django 2.1.1

django-admin is a commandline tool installed along with Django

Start project

django-admin startproject first_project

This creates a folder first_project with a bunch of files:

init.py (makes the directory a package)

settings.py (This is where we store all our project settings)

urls.py (stores URL patterns for our project

wsgi.py (Acts as webserver gateway interface. It will help us deply our webapp to production)

manage.py (Majority of our code will go in here)

Run project

python manage.py runserver

Starting development server at http://127.0.0.1:8000/

Create a Django app

Django apps can be plugged into Django projects to render a specific application

python manage.py startapp first_app

This creates a folder first_app with a bunch of files to be used in Model View Template Pattern:

init.py (makes the directory a package)

admin.py (This is where we register models)

apps.py (application specific configurations)

models.py (Store applications data models. Specific entities and relationship between data)

tests.py (Series of functions of test our application code)

views.py (functions that handle request and return responses)

Migration directory (Stores database specific information as it relates to the models)

Adding app to Django project

This is done by modifying settings.py to let first_project know about first_app

Add first_app to the list INSTALLED_APPS

INSTALLED_APPS = [
    # Default apps
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #Created apps
    'first_app'
]

Creating a View

In views.py, create a function index and add it to urls.py

# Create your views here.
from django.http import HttpResponse

def index(request):
    #request is an object from django.http
    return HttpResponse("Hello World!")

In urls.py, add a path to views.index in urlpatterns

##Default
from django.contrib import admin
from django.urls import path
##New import
from first_app import views

urlpatterns = [
    path('', views.index, name="index"), ##Maps applications view to the url
    path('admin/', admin.site.urls), ##Appears default
]

Running

python manage.py runserver

opens a URL with Hello world text

Mapping of URLS from other directories

It is better to have url mappings of each app separate.

Therefore, we have a separate urls.py in the app folder and include the following path in urls.py of the project,

from django.urls import path, include

urlpatterns = [
    ...,
       path('first_app/', include('first_app.urls')), # url : "127.0.0.1:8000/first_app"
       # 'first_app' can be any arbitary string
       # path('new_ext/', include('first_app.urls'))
    ...
]

The URL will be www.domainname.com/first_app/...

eg: http://127.0.0.1:8000/first_app

Templates

We dont want the HTML inside python. So we want to replace this line in the views with HTML files

HttpResponse("Hello World!")

For this, we put the HTML files in a template folder and add it to our settings

Create a new folder templates in the project folder

In settings.py, add the path of this directory to TEMPLATES dict

#Dir pointing to manage.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
##template dir
TEMPLATE_DIR = os.path.join(BASE_DIR,"templates")
#../first_project/templates
TEMPLATES = [
    {
        ...,
        'APP_DIRS': True,
        'DIRS': [TEMPLATE_DIR,],

        ...,
    },
]

NOTE: By default, django will automatically search in first_app/templates if APP_DIRS is set True. If we place index.html in first_app/templates we do not have to modify settings.py

index.html (include the template variable to have text injection from views)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>First App</title>
  </head>
  <body>
    <h1>Hello! This is index.html</h1>

    <!-- template variabe -->
    
  </body>
</html>

views.html

def index(request):
    my_dict = { 'insert_me':"Hello I am from views.py"}
    return render(request,'index.html',context=my_dict)
    #../first_project/templates/index.html

Output

Hello! This is index.html

Hello I am from views.py

NOTE: text from template variable in views.py is also executed

Injecting Static files (Images, CSS, JS etc)

This is requried to let python find the files (say CSS, JS or image files) in our directory

Create a new directory and add its path to STATICFILES_DIRS in settings.py. If the files are placed under first_app/static, we dont have to modify settings.py

STATIC_DIR = os.path.join(BASE_DIR,"static")
#include static dir here
STATICFILES_DIRS = [
        STATIC_DIR,
        ]

Images and other static media are placed under this directory

They can be accessed by appending the path to URL. (If an image seo-og.jpg is placed under static/first_app/images/)

then http://127.0.0.1:8000/static/first_app/images/seo-og.jpg

To Use the image in HTML file, append the source with % static and include {% load staticfiles %} at the top of HTML file

<!DOCTYPE html>
{%  load staticfiles  %}
<html>
  <head>
    <meta charset="utf-8">
    <title>First App</title>
  </head>
  <body>

     <!-- image injection -->
    <img style="width:500px;height:500px;" src="{%  static "first_app/images/seo-og.jpg"  %}" alt="Couldnt find">


  </body>
</html>

Can also include stylesheet

<link rel="stylesheet" href="{%  static "first_app/css/mystyle.css"  %}" />