Thursday, October 15, 2020

Using Static Files

First of all, to be able to use static files, we need to add some setting in the setting.py module as follow:

"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 3.1.2.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'h4!#au%8tb_9@oe+c0te=g=u%cfxb8t8fy%7+(gx2+51!t*b+s'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    # Simplified static file serving.
    # https://warehouse.python.org/project/whitenoise/
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'mysite.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        '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',
            ],
        },
    },
]

WSGI_APPLICATION = 'mysite.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Phnom_Penh'

USE_I18N = True

USE_L10N = True

USE_TZ = True


BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

STATIC_URL = '/static/'

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
  os.path.join(BASE_DIR, 'static'),
)

# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Next, we need to create a folder called "static" at the top level of our Djavgo app. In that folder we could create a number of subfolder following our need as in the picture below.

To use static file in template file, we need to define the link to the static folder first using Django template language "load", next, we could use that link to define the route to different static files in the static folder.

<!--templates/index.html-->
{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>{{blogTitle}}</title>
    <link rel="icon" href="{% static 'images/site_logo.png' %}" >
    <link rel="stylesheet" href="{% static 'css/main.css' %}" >
    <link rel="stylesheet" href="{% static 'fonts/setup.css' %}" >
    <script src="{% static 'js/jQuery.js' %}"></script>
    <script src="{% static 'js/main.js' %}"></script>
  </head>
  <body>
    {{message}}
  </body>
</html>

GitHub: https://github.com/Sokhavuth/django
Heroku: https://khmerweb-django.herokuapp.com/

Wednesday, October 14, 2020

Creating Home Page

After creating the main Django application called "project" in Django term, we could also create a number of separated applications and link them to the main application for them to run also when the the main application starts. For example, to create a separated application for the home page, we need to write a statement as below:

python manage.py startapp home

Next, we need to create the first controller or view in Django term in order to display the home page of our application.

#home/views.py
from django.http import HttpResponse

def index(request):
  return HttpResponse('Hello World!')

To run the code in the module views.py above, we need to create a route or URLconfig to this module as below:

#home/urls.py
from django.urls import path

from . import views

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

Finally, to run the code in the module home/urls.py, we have to include this file in the module mysite/urls.py as below:

#mysite/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
  path('', include('home.urls')),
  path('admin/', admin.site.urls),
]

GitHub: https://github.com/Sokhavuth/django
Heroku: https://khmerweb-django.herokuapp.com/

Creating HTML Page

What the other web frameworks called «views», in Django term, it is «template» in which we can use a template engine or language with HTML markup language to create different HTML page for different purposes.

As the result, the concept «model-views-controller» in other web frameworks, is tranlated to be «model-template-view» in Django framework. However, before be able to use template page in Django app, we need to create a folder to store those template pages and setup the path to that folder in the module setting.py locating in mysite folder.

Although we can name the template folder anything we like, but conventionally, web developers around the world used to name it as «templates».

"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 3.1.2.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'h4!#au%8tb_9@oe+c0te=g=u%cfxb8t8fy%7+(gx2+51!t*b+s'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'mysite.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        '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',
            ],
        },
    },
]

WSGI_APPLICATION = 'mysite.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Phnom_Penh'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
#mysite/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
#mysite/views.py
from django.http import HttpResponse
from django.shortcuts import render

context = {'blogTitle':"Khmer Web", 'message':"Hello World!"}

def index(request):
  return render(request, 'index.html', context)
<!--templates/index.html-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>{{blogTitle}}</title>
    
  </head>
  <body>
    {{message}}
  </body>
</html>

GitHub: https://github.com/Sokhavuth/django
Heroku: https://khmerweb-django.herokuapp.com/

Tuesday, October 13, 2020

Route & View

In Django term, routing is the defining of «URLconfig» in the module urls.py. Moreover, all routes are linked to different controller or «view» in Django term. Conventinally, all controllers or views are sotred in a module called «views.py». In fact, to create a route linked to a function that would run when we open the home page of our Django app, we should write the code as below:

#mysite/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
#mysite/views.py
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello World!")

In sum, routing in Django could be done as below:

from django.urls import path, re_path

from . import views

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
    path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
]

GitHub: https://github.com/Sokhavuth/django
Heroku: https://khmerweb-django.herokuapp.com/