4. Django Development

4.1. Start Django Project

  1. create directory “mysite” for project

  2. setup virtual environment

  3. install Django into virtual environment

    $ pip install "Django==3.1.2"
    $ # innstall psycopg2 requied for postgrsql
    $ pip install psycopg2
    
  4. start python and

    >>> django-admin startproject mysite .
    
  5. if you have Pycharm community edition open to project “mysite”. This would be the first directory named “mysite”.

  6. open ‘terminal’ window at bottom of Pycharm. You should see “(venv)” as part of the directory location.

  7. verify django is installed using Pycharm terminal window.

    $ python import django
    
    >>> django.get_version()
    '3.08'
    >>>
    
  8. Most likely it will throw an error. Then go to Settings->Project->Project Interpretor->+ and install django from ‘Avalable Packages’.

  9. Django applications contain models.py that defines data models. To create tables associated with the models run the following commands

    $ cd mysite
    $ python manage.py migrate
    
  10. verify that the site works by clicking on ‘127.0.0.1:8000’

4.2. Create and Activate a Simple App

From root directory of Django project (not necessarily Pycharm project) key in

$ python manage.py startapp blog

Then write python code for a Post model with the data model for the app.

Activate the app by: In settings.py add blog.apps.BlogConFig to end of INSTALLED_APPS section

4.3. Apply the Migration:

To create DB tables for your app, use command below. This reflects the creation of a new model.

$ python manage.py makemigrations blog

To sync your new app table(s) with the django project use. Now a new table exists in the DB

$ python manage.py migrate

If you wish to look at the SQL use

$ python manage.py sqlmigrate blog 0001

Run the Django Server

4.4. Create Administration Site for Models

First create a superuser:

$ python manage.py createsuperuser

Then add the requested data and don’t lose the username and password

4.5. Canonical URLs

A canonical URL is the preferred URL for a web resource. The canonical URL is the most represenative from a duplicate set of pages. A page with URLs mypage.com?id=1234 and mypage.com/id/1234 would only have one of the address as a canonical URL. Django’s convention is to add a get_absolute_url() method in the model to set and return the canonical URL.

reverse is a utility function Django provides to reference an object by its URL template name, the optional name at the end of a path variable in url.py

4.6. URL Patterns

URL patterns allow you to map URLs to views. A URL pattern is composed of

  1. A string pattern

  2. A View

  3. Optionally a name that allows you to name the URL project wide.

Create a urls.py file in the directory of the application ‘name’. Angle bracketts ‘< >’, when used capture the values from the URL. Path Converters

To define complex URL patterns use re_path() for Python regular expressions.

4.6.1. Path Converters

  1. str - Matches any non-empty string, excluding the path separator, ‘/’.This is the default if a converter isn’t included in the expression

  2. int - Matches zero or any positive integer. Returns an int.

  3. slug - Matches any slug string consisting of ASCII letters or numbers, plus the hyphen and underscore characters. For example, building-your-1st-django-site.

  4. path - Matches any non-empty string, including the path separator, ‘/’. This allows you to match against a complete URL path rather than a segment of a URL path as with str

4.6.2. The Main URL Patterns in the Project

Finally make sure you include the URL patterns of the application in the URL patterns of the project. You need to edit the urls.py file located in the project directory of your project.

urlpatters = [
    path('admin/', admin.site.urls),
    path('app/', inlcude('app.urls', namespace='app')),
]

Namespaces have to be unique across the entire project.

4.7. Views

The request object parameter is required vy all views. Url patterns map URLs to views and views decide which data gets returned to the user.

4.8. Templates

{% load static %} tells Django to load the static template tags that are provided by the django.contrib.staticfiles application, which is contained in the INSTALLED_APPS setting.

4.9. Forms

To create a form from a model, you just need to indicate which model to use to build the form in the Meta class of the form. Django introspects the model and builds the form dynamically for you.

4.10. Set Up Simple Mail Send in Django

Much more info is readily available than what is listed below

Default setting with output going to console

EMAIL_HOST = 'localhost'
EMAIL_PORT = 25     #   POP is port 110
EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

Setting for smtp email server

EMAIL_HOST = <'mail_server_url'>
EMAIL_PORT = 25
EMAIL_HOST_USER = <'user@domain_name'>
EMAIL_HOST_PASSWORD = <'password'>
EMAIL_USE_TLS = True    # Wheather to sue a TLS secure connection
EMAIL_USE_SSl = True    # use an implicit TLS secure connection

4.11. Custom Template Tags

  • simple_tag: Processes the data and returns a string

  • inclusion_tag:Processes the data and returns a rendered template

Modules that contain template tags must define a variable called register to be a valid tag library.

Use the @register.simple_tag decorator or the @register.inclusion_tag(‘<template rendered>’) to register your tags. Before a tag can be used in a template {% load_blog_tags %} to the top of the template. Also the server must be restarted.

Inclusion tags must return a dictionary of values.

4.12. Custom User Model

When starting a new project set up a custom user model, even if the regular User model is good enough for the project. The custom user model will default to the regulare User model but you will be able to modify the custom user model in the future if needed.

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

Don’t forget to point AUTH_USER_MODEL to it. Do this before creating any migrations or running manage.py migrate for the 1st time. Also register the model in the app’s admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models inport User

admins.site.register(User, UserAdmin

Changing AUTH_USER_MODEL after creating the database tables is really screwy since you have a bunch of foreign keys and many-to-many relationships. You will descend into dependency hell!!!

Reusable apps shouldn’t implement a custom user model. https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#substituting-a-custom-user-model

4.13. SQL ORM Translate

  • Fetch all rows: SELECT * FROM T; -> P.objects.all()

  • Fetch columns from table: SELECT n, a FROM P; -> P.objects.only(‘n’, ‘a’)

  • Fetch using WHERE: SELECT * FROM T WHERE id = 1; -> P.objects.filter(id = 1)