Django

Django First App

mkdir firstapps

cd firstapps

conda install -c anaconda virtualenv 

virtualenv myenv

source myenv/bin/activate

django-admin  startproject wordcount

cd wordcount
python manage.py runserver

 

python manage.py migrate

python manage.py createsuperuser

python manage.py startapp wcount

wordcount/settings.py

"""
Django settings for my_project project.

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

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

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'pzk&t78=1glwsae59e&q-_%_v$ytm$=g1(01w813ax@#an57zz'

# 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',
 'wcount',
]

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 = 'my_project.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',
 ],
 },
 },
]
LOGIN_REDIRECT_URL = 'home' 
LOGOUT_REDIRECT_URL = 'home'


WSGI_APPLICATION = 'my_project.wsgi.application'


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

DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.sqlite3',
 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
 }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/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/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


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

STATIC_URL = '/static/'

wordcount/urls.py

from django.urls import path
from wcount import views

urlpatterns = [
   path('', views.homepage, name='home'),
   path('count/', views.count, name='count'),
   path('about/', views.about, name='about1'),
]

wcount/views.py

from django.http import HttpResponse
from django.shortcuts import render
import operator

def homepage(request):
 return HttpResponse('<h1>Home Page</h1>')

def about(request):
 return HttpResponse('<h1>About Page</h1>')
def count(request):
 return HttpResponse('<h1>I will do the count for you.</h1>')

If we are using this command in command prompt:directly copy and paste

If you want to create a new folder or file use VScode/explorer

mkdir wcount/templates

cd templates

mkdir wcount

cd wcount

create wcount/templates/wcount/about.html

<h1> About us from template file.</h1>

create wcount/templates/wcount/home.html

<h1> Home page template file.</h1>

create wcount/templates/wcount/count.html

<h1> I will count the value for you.</h1>

update wcount/view.py

from django.http import HttpResponse
from django.shortcuts import render
import operator

def homepage(request):
 return render(request, 'wcount/home.html')

def about(request):
 return render(request, 'wcount/about.html') 
def count(request):
 return render(request, 'wcount/count.html')

make sure that you run the server before checking in browser

Check if it is working

WordCount

 

wcount/templates/wcount/home.html

<h1>WORD COUNT</h1>
 
<a href="{% url 'about1' %}">About</a>

<form action="{% url 'count' %}">
 <textarea cols="40" rows="10" name="fulltext"></textarea>
 <br />
 <input type="submit" value="Count!" />
</form>

Let explore GET

wcount/views.py

from django.http import HttpResponse
from django.shortcuts import render
import operator

def homepage(request):
 return render(request, 'wcount/home.html')

def about(request):
 return render(request, 'wcount/about.html')

def count(request):
 fulltext = request.GET['fulltext']

 wordlist = fulltext.split()

 worddictionary = {}

 for word in wordlist:
     if word in worddictionary:
         #Increase
         worddictionary[word] += 1
     else:
         #add to the dictionary
         worddictionary[word] = 1

 sortedwords = sorted(worddictionary.items(), key=operator.itemgetter(1),      reverse=True)

 return render(request, 'wcount/count.html',{'fulltext':fulltext,'count':len(wordlist),'sortedwords':sortedwords})

wordcount/wcount/templates/wcount/count.html

<h1>There are {{ count }} words in your text</h1>
 
<a href="{% url 'home' %}">Start Again</a>

<h1>Your Text:</h1>
{{ fulltext }}

<h1>Word Count:</h1>

{% for word, counttotal in sortedwords %}

{{ word }} - {{ counttotal }}
<br />



{% endfor %}

wcount/templates/wcount/about.html

<h2>About</h2>
 
<p>Hey my name is Nick and I live to count words. Hope you find the count you need!</p>
<a href="{% url 'home' %}">Retrun Home</a>

Copyright 2019

Let us try again

http://127.0.0.1:8000

Results of the app

 

let us build another  app

create a project

django-admin startproject wordcount

tree wordcount

you can get help from manage.py

python manage.py help

we can change name of the folder

ls

wordcount

tree

mv wordcount/ wordcount-project

cd wordcount-project

runserver

python manage.py runserver

check browser

check the directory structure again

tree

urls.py

"""wordcount URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:

   https://docs.djangoproject.com/en/2.0/topics/http/urls/

Examples:
Function views
   1. Add an import: from my_app import views
   2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
   1. Add an import: from other_app.views import Home
   2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
   1. Import the include() function: from django.urls import include, path
   2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""


from django.contrib import admin
from django.urls import path

urlpatterns = [
   url(r'^admin/', admin.site.urls),
]

create admin account (superuser)

python manage.py runserver

python manage.py migrate

create superuser

python manage.py createsuperuser

admin

Enter Credential

you can see the  user data

Explore admin feature

we can add more users if we want

 

add an app

python manage.py startapp mycontacts

tree

update  wordcount/urls.py

"""wordcount URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:

   https://docs.djangoproject.com/en/2.0/topics/http/urls/

Examples:
Function views
   1. Add an import: from my_app import views
   2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
   1. Add an import: from other_app.views import Home
   2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
   1. Import the include() function: from django.urls import include, path
   2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""

from django.conf.urls import include, url
from django.contrib import admin
from mycontacts import views

urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'^$', views.show),
   url(r'^add/', views.add),
]

check for error

 

update  mycontacts/views.py

from django.shortcuts import render
from .forms import AddForm
from .models import Contact
from django.http import HttpResponseRedirect
from django.http import HttpResponse


def show(request):
   """
   This function gets all the members in your Database through your Model
   Any further usage please refer to:                          
   https://docs.djangoprojectcom/el/1.10/ref/models/querysets/
   """
   contact_list = Contact.objects.all()
   #return HttpResponse('Hello Amar')
   #return render(request, 'mycontacts/show.html',{'contacts': contact_list})
   return render(request, 'mycontacts/show.html',{'contacts': contact_list})


def add(request):

   """ 
   This function is called to add one contact member to your contact list in your                                Database """
 
   if request.method == 'POST':
      django_form = AddForm(request.POST)
      if django_form.is_valid():

        """ Assign data in Django Form to local variables """
        new_member_name = django_form.data.get("name")
        new_member_relation = django_form.data.get("relation")
        new_member_phone = django_form.data.get('phone')
        new_member_email = django_form.data.get('email')

        """ This is how your model connects to database and create a new member """
        Contact.objects.create(
           name = new_member_name,
           relation = new_member_relation,
           phone = new_member_phone,
           email = new_member_email,
           )
        contact_list = Contact.objects.all()
        return render(request, 'mycontacts/show.html',{'contacts': contact_list})

      else:
        """ redirect to the same page if django_form goes wrong """
        return render(request, 'mycontacts/add.html')
   else:
     return render(request, 'mycontacts/add.html')

 

mycontacts/models.py

from django.db import models

class Contact(models.Model):

   """ For other types of fields for different purpose, please refer to: https://docs.djangoproject.com/ja/1.10/ref/models/fields/ """

   name = models.CharField(max_length=200)
   relation = models.CharField(max_length=200)
   phone = models.CharField(max_length=200)
   email = models.CharField(max_length=200)

   def __str__(self):
      return self.name

Tell Django about new app

 update wordcount/setting.py

"""
Django settings for wordcount project.

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

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

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '_x&i7*x5()r@xzktgn1(j!+4by1%^@d8r7*#2)dv09gixx1)7t'

# 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',
 'mycontacts',
]

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 = 'wordcount.urls'

TEMPLATES = [
 {
 'BACKEND': 'django.template.backends.django.DjangoTemplates',
 'DIRS': [],
 '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 = 'wordcount.wsgi.application'


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

DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.sqlite3',
 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
 }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/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/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


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

STATIC_URL = '/static/'

mycontacts/forms.py

from django import forms
from .models import Contact

class AddForm(forms.Form):

   class Meta:
      model = Contact
      fields = ('name', 'relation', 'phone', 'email',)

Register your model

Admin is used to register your Model in your Database.

mycontacts/admin.py

from django.contrib import admin
from .models import Contact

admin.site.register(Contact)

 

Make migrations

python manage.py makemigrations

check model

 

write your model to DB

python manage.py migrate

see what is there in the DB now

python manage.py inspectdb

Run server and notice error

python manage.py runserver

Templete’s error

Let us see your model from model

click on add contact

we will See Error Problem in sqllite
Let us use posrgreSQL

Only change in settings.py – that is the beauty

pip install psycopg2
conda install mysqlclient

Postgres terminal

 

 

we can change the settings.py in Databases

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.postgresql',
       'NAME': 'contacts',
       'USER':  'postgres',
       'PASSWORD': 'abcd1234',
       'HOST':'localhost',
       'PORT': 5432,
   }
}

New DB you need to do migration 

python manage.py runserver

python manage.py migrate

 

 

Now let us add users

how to handle objects?

Now you can see meaningful objects

 

Let us add templates

mycontacts/templates/mycontacts/add.html

{% extends 'mycontacts/background.html' %}
{% load staticfiles %}
{% block content %}

 <div class="container-add">
 <div class="col-xs-4 col-sm-4 col-md-4 col-lg-4 col-xs-offset-3">
 
 <form id="add-contact-form" class="form" action="#" method="POST" role="form">
 
 {% csrf_token %}
 {{ form.as_p }}
 
 <div class="form-group">
 <label class="form-label">Name</label>
 <input type="text" class="form-control" id="name" name="name" placeholder="Name" tabindex="1" required>
 </div>
 <div class="form-group">
 <label class="form-label">Relation</label>
 <input type="text" class="form-control" id="relation" name="relation" placeholder="Relation" tabindex="2" required>
 </div>
 <div class="form-group">
 <label class="form-label">Phone</label>
 <input type="text" class="form-control" id="phone" name="phone" placeholder="Phone" tabindex="3" required>
 </div>
 <div class="form-group">
 <label class="form-label" for="email">Email</label>
 <input type="text" class="form-control" id="email" name="email" placeholder="Email" tabindex="4" required>
 </div> 
 
 <div class="text-center">
 <button type="submit" class="btn">Confirm</button>
 </div>
 </form>
 
 </div>
 </div>

{% endblock content %}

mycontacts/templates/mycontacts/show.html

{% extends 'mycontacts/background.html' %}
{% load staticfiles %}

{% block content %}
<div class="container-show">
 <ul class="grid" style="list-style-type: none">
 
 {% for contact in contacts %}
 <li>
 <div>
 <h2 class="name">{{ contact.name }}</h2>
 <div class="relation">{{ contact.relation }}</div>
 <div class="phone">{{ contact.phone }}</div>
 <div class="email"><a href='{{ contact.email }}'>{{ contact.email }}</a> </div>
 </div>
 </li>
 {% endfor %}
 
 </ul>
</div> 
{% endblock content %}

mycontacts/templates/mycontacts/background.html

{% load staticfiles %}
<!DOCTYPE HTML>
<html lang="en-US">
<head>
 
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=11; IE=10; IE=9; IE=8; IE=7; IE=EDGE" />

 <!--latest Bootstrap theme-->
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous">
 <!-- Optional theme -->
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" integrity="sha384-aUGj/X2zp5rLCbBxumKTCw2Z50WgIr1vs/PFN4praOTvYXWlVyh2UtNUU0KAUhAX" crossorigin="anonymous">
 
 <link rel="stylesheet" href="{% static 'css/show.css' %}">
 <link rel="stylesheet" href="{% static 'css/add.css' %}">
 
 <script type="text/javascript" src="//code.jquery.com/jquery-1.11.3.min.js"></script>
 <script type="text/javascript" src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>

 <script type="text/javascript" src="{% static 'js/show.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/add.js' %}"></script>
 
 <title> My Contacts </title>

</head>
<body>
 <div class="header">
 <h2><a href="/">My Contacts</a></h2>
 <div class="pull-right">
 <a href="/add">Add</a> 
 <!--<a href="{% url 'add'}">Add</a>-->
 </div>
 </div>
 <div class="body">
 {% block content %}
 {% endblock content %}
 </div> 
 <div class="footer">
 <h2>Django Introduction & Tutorial</h2>
 <p>Presented by <a href="https://www.facebook.com/WOIR-Software-India-Pvt-Ltd-328594120836182/?ref=br_rs">WOIR Software</a></p>
 </div>
</body>
</html>

create a folder static in your app and name it

create folder in mycontacts

mkdir static 

cd static

mkdir css

mkdir js

mycontacts/static/css/add.css

textarea {
 resize: none;
}

.container-add{
 padding-top: 15%;
 padding-left: 15%;
}

.form-label {
 font-size: 13px;
 color: #0B3B39;
 margin: 0;
 display: block;
 opacity: 1;
 -webkit-transition: .333s ease top, .333s ease opacity;
 transition: .333s ease top, .333s ease opacity;
}

.form-control {
 border-radius: 0;
 border-color: #ccc;
 border-width: 0 0 2px 0;
 border-style: none none solid none;
 box-shadow: none;
}

.form-control:focus {
 box-shadow: none;
 border-color: #0B3B39;
}

.js-hide-label {
 opacity: 0; 
}

.js-unhighlight-label {
 color: #999;
}

.btn{
 background: 0 0 #ffffff;
 border: 1px solid #9FB0A9;
 border-radius: 3px;
 color: #9FB0A9;
 font-family: "Raleway", sans-serif;
 font-size: 16px;
 line-height: inherit;
 margin: 30px 0;
 padding: 10px 50px;
 text-transform: uppercase;
 transition: all 0.25s ease 0s;
}

.btn:hover,.btn:active, .btn:focus {
 border-color: #0b3B39;
 color: #0b3B39;
 transform: translateX(-1px);
}

mycontacts/static/css/show.css

html{
 height: 100%;
}
.name{
 font-size: 50px;
}
.email{
 color: #0B6121;
}
.grid {
 overflow: hidden;
 padding: 2em 2em;
 max-width: 76em;
 margin: 0 auto;
 }
 .grid li {
 
 padding: 0 0.8em 1.3em ;
 }
 .grid li > div {
 border-bottom: 1.8px solid #cccccc;
 border-right: 1.4px solid #cccccc;
 border-left: 0.7px solid #cccccc;
 border-top: 0.6px solid #cccccc;
 
 background: #ffffff;
 padding: 7em 2em;
 text-align: center;
 }
 .grid li a {
 color: #0B6121;see output
 }
 
 @media all and (min-width: 27em) {
 .grid li {
 width: 100%;
 float: left;
 }
 }
 
 @media all and (min-width: 40em) {
 .grid li {
 width: 50%;
 }
 .grid li.wide {
 width: 100%;
 }
 }
 @media all and (min-width: 60em) {
 .grid li {
 width: 33%;
 }
 .grid li.wide {
 width: 100%;
 }
 }
.container-show{
 padding-top: 10%;
 padding-bottom: 7%;
}

.js-global-header-scrolling {
 top: -4em; /* Height of the header */
}

body {
 position: relative;
 margin: 0;
 min-height: 100%;
}

.footer {
 color:white;
 text-align: center;
 padding: 0.5px;
 
 width: 100%; 
 height: 95px;
 background-color: #0b3B39;
 
 
 position: absolute; /*keeps the footer at the bottom*/
 right: 0;
 bottom: 0;
 left: 0;
}

.header {
 color:white;
 background-color: #0B3B39;
 width: 100%;
 position:fixed;
 text-align: center;
 transition: top .2s ease-in;
}

.header a {
 text-decoration:none;
 display:block;
 color:white;
 background: url(image url) center center no-repeat;
 margin-right: 12px;
 padding: 15px 25px;
}

.header a:hover {
 text-decoration:none;
 color:white;
 background-color: #0B6121;
 display:block;
 padding: 15px 25px;
}

.header h2 a {
 text-decoration:none;
 color:white;
 padding: 0px 0px;
}

.header h2 a:hover {
 text-decoration:none;
 color:white;
 background-color: #0B3B39;
 padding: 0px 0px
}

mycontacts/static/js/add.js

$(document).ready(function() {
 // Test for placeholder support
 $.support.placeholder = (function(){
 var i = document.createElement('input');
 return 'placeholder' in i;
 })();

 // Hide labels by default if placeholders are supported
 if($.support.placeholder) {
 $('.form-label').each(function(){
 $(this).addClass('js-hide-label');
 }); 

 // Code for adding/removing classes here
 $('.form-group').find('input, textarea').on('keyup blur focus', function(e){
 
 // Cache our selectors
 var $this = $(this),
 $parent = $this.parent().find("label");

 if (e.type == 'keyup') {
 if( $this.val() == '' ) {
 $parent.addClass('js-hide-label'); 
 } else {
 $parent.removeClass('js-hide-label'); 
 } 
 } 
 else if (e.type == 'blur') {
 if( $this.val() == '' ) {
 $parent.addClass('js-hide-label');
 } 
 else {
 $parent.removeClass('js-hide-label').addClass('js-unhighlight-label');
 }
 } 
 else if (e.type == 'focus') {
 if( $this.val() !== '' ) {
 $parent.removeClass('js-unhighlight-label');
 }
 }
 });
 } 
});

mycontacts/static/js/show.js

//Requires JQuery or Zepto
$(document).ready(function(){

// Cache Header
var $header = $('.header');

// Get height of global-header to use later as starting point
var $hHeight = $header.height();

// Set initial position to current position on page
var prevTop = $(window).scrollTop();

// Scroll event
$(window).on('scroll', function(e) {
 var st = $(this).scrollTop(); // Set scroll location
 if (st > prevTop && st > $hHeight) { 
 $header.addClass('js-global-header-scrolling');
 } else {
 $header.removeClass('js-global-header-scrolling');
 }
 prevTop = st;
});
});

see output

Django login/logout

Django 2.1 with the built-in user authentication system

Let us do the setup –

create a new accounts directory for our code on the Desktop

install Django with Pipenv

start the virtual environment shell

create a new Django project called my_project

create a new Sqlite database with migrate

run the local server

Create login/logout project

cd ~/Desktop
mkdir accounts && cd accounts 
pip install django==2.0.2 
django-admin.py startproject my_project 
python manage.py migrate
python manage.py runserver
update file   my_project/urls.py
from django.contrib import admin
from django.urls import include
from django.urls import path
from django.views.generic.base import TemplateView
urlpatterns = [
 path('admin/', admin.site.urls),
 path('myaccounts/', include('django.contrib.auth.urls')), 
 path('', TemplateView.as_view(template_name='home.html'), name='home'), # new

]

 

templates/registration/login.html

{% extends 'base.html' %}

{% block title %}Login{% endblock %}

{% block content %}
<h2>Login</h2>
<form method="post">
 {% csrf_token %}
 {{ form.as_p }}
 <button type="submit">Login</button>
</form>
{% endblock %}

update the setting.py file to tell Django to look for a templates folder at the project level 

add path  settings.py in  templates part

'DIRS' : [os.path.join.(BASE_DIR, 'templates')],

login url

create one more user

python manage.py createsuperuser

templates/home.html

{% extends 'base.html' %}

{% block title %}Home{% endblock %}

{% block content %}
{% if user.is_authenticated %}
 Hi {{ user.username }}!
{% else %}
 <p>You are not logged in</p>
 <a href="{% url 'login' %}">login</a>
{% endif %}
{% endblock %}

templates/base.html

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>{% block title %}Django Auth Tutorial{% endblock %}</title>
</head>
<body>
 <main>
 {% block content %}
 {% endblock %}
 </main>
</body>
</html>

login user

logout

update file  templates/home.html

{% extends 'base.html' %}

{% block title %}Home{% endblock %}

{% block content %}
{% if user.is_authenticated %}
 Hi {{ user.username }}!
 <p><a href="{% url 'logout' %}">logout</a></p>
{% else %}
 <p>You are not logged in</p>
 <a href="{% url 'login' %}">login</a>
{% endif %}
{% endblock %}

update file  my_project/settings.py

LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'

logout