django_notes (3)
django_notes (3)
With the help of a framework, you don’t have to handle the hassles of web development and
its various components.
Therefore, it makes the life of a web application developer much easier as they don’t have to
code from scratch.
Source : medium.com
MVC vs MVT
MVC architecture
Source : medium.com
MVC vs MVT
MVT architecture
MVT stands for Model View Template. In MVT, there is a predefined template for user
interface.
Seeting.py
Key value pair
DEBUG=true (In production keep it false)
Installed_apps : Django has concept called as apps. These are default apps.
Create an app with name “pages”
Django uses the concept of projects and apps to keep code clean and readable.
A single Django project contains one or more apps within it that all work together to power a web
application.
Project Dir-FB
For example, a real-world Django e-commerce site might have one app for user authentication,
another app for payments, and a third app to show the item listing details.
create our first app which we’ll call pages
13
Create apps inside project
$ python manage.py startapp pages
It will create pages app(folder) with few files
Things to remember
$django-admin startapp appName
# pages/urls.py
from django.urls import path
urlpatterns = [
path('', views.home, name='home'),
]
def home(request):
return HttpResponse(‘<h1>Hello, I am learning Django!</h1>')
Register the links of pages app into main urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('', include('pages.urls')),
path('admin/', admin.site.urls),
]
More correct way is to handle the request and send the response is through Django
Template view.
Template view
Template view intro
Build, and deploy a Pages app that has a homepage and an about page. Using class-based
views and templates which are the building blocks of Django’s
21
Create template at project level
Create template at project level and subfolder for the applications.
Next we need to update settings.py to tell Django to look at the project-level for templates
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
},
]
Update views.py function
Update functions to return html page in response.
# pages/views.py
from django.shortcuts import render
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Django session</title>
</head>
<body>
{% block content %} {% endblock %}
</body>
</html>
Update html pages
<!– index.html --> <!– about.html -->
All images, css, js files needed to refer into project can be treated as static
files.
Static files configuration
Create static folder inside project -> project app directory
<div class="row">
<div class="col-md-4">
</div>
<div class="col-md-4">
</div>
<div class="col-md-4">
<a href="#">
</a>
<a href="#">
</a>
<a href="#">
</a>
<a href="#">
</a>
</div>
</div>
</div>
</div>
</section>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top">
<div class="container">
</a>
<span class="navbar-toggler-icon"></span>
</button>
<ul class="navbar-nav">
</li>
</li>
</li>
</ul>
</li>
Login</a>
</li>
</ul>
</div>
</div>
</nav>
URL linking
To link the page developer uses href with page name inside html.
To make a link active/inactive dynamically, we need to add if-else logic with Django code
Highlight the link in navbar cont..
<li
{% if '/' == request.path %}
class="nav-item active mr-3"
{% else %}
class="nav-item mr-3"
{% endif %}
>
<a class="nav-link" href="{% url 'index' %}">Home</a>
</li>
<li
{% if 'about' in request.path %}
class="nav-item active mr-3"
{% else %}
class="nav-item mr-3"
{% endif %}
>
New App – listing
As we have to list the homes or search with specific criteria. Better to have separate app.
Listing app
$python manage.py startapp listings
mysql>use restful_db
Where root as your user, localhost as your URL, and password as your password
flush privileges;
File: mysqlclient-1.4.6-cp37-cp37m-win32.whl
Then
$pip install C:\\Users\\kunalpag\\downloads\\mysqlclient-1.4.6-cp37-cp37m-win32.whl
2) Realtor
• Id, name, photo, description, email, phone, isBestSeller,
3) Contact
• Id, user_id, name, email, phone, isBestSeller, message, contact_date
• listing_id
Create listing model
• We can map DB table to models in python.
• Goto listing app-> models.py to write the model code
• Use documentation for the reference
https://docs.djangoproject.com/en/2.0/ref/models/fields/
from django.db import models
Create a model- Listing
from datetime import datetime
from realtors.models import Realtor sqft=models.Integer()
photo_main=models.ImageField(upload_to='photos
# Create your models here. /%Y/%m/%d/')
def __str__(self):
return self.name
Models migration
These tables are just models in python.
They are not in DB yet- like we don’t have any table which represent the listing,relators.
2) Migrate
This will connect to DB and write the content present in migrations folder
1) python manage.py makemigrations Migration commands
Migrations for 'realtors':
realtors\migrations\0001_initial.py
- Create model Realtor
Migrations for 'listings':
listings\migrations\0001_initial.py
- Create model Listing
We don’t see any tables related to listing, relators models. Need to register the models in
admin.
# Open listings->admin.py Register the models
admin.site.register(Listing)
admin.site.register(Realtor)
Setting the media folder
Open setting files and define media folder path.
Go at the end.
urlpatterns = [
# http://localhost:8000/
# http://localhost:8080/about
path('', include('pages.urls')),
# http://localhost:8000/listings/
# http://localhost:8000/listings/10
# http://localhost:8000/listings/search
# http://localhost:8000//search invalid
path('listings/', include('listings.urls')),
path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Customize the Admin Area
Lets customize the admin page
{% extends 'admin/base.html' %}
{% load static %}
{% block branding%}
<h1 id="head">
<img src="{% static 'img/logo.png' %}" alt="Real estate-admin page" class="brand_img" height="50"
width="80">
Real estate-admin page </h1>
{% endblock %}
Customize the Admin Area
Before After
Convert the pages from static to dynamic
Dynamic listings of properties
Convert listings of properties from static content to dynamic.
Listings-> view.py
def index(request):
listings = Listing.objects.all()
context = {
'propListings' : listings
}
return render(request,'listings/listings.html',context)
Display the data i.e json array using loops. Dynamic listings of properties
<!-- Listings -->
<section id="listings" class="py-4">
Logic <div class="container">
<div class="row">
{% if propListings %}
<div class="row"> {% for listing in propListings %}
{% if propListings %} <div class="col-md-6 col-lg-4 mb-4">
<div class="card listing-preview">
{% for listing in propListings %} <img class="card-img-top"
<!-- Html code goes here --> src="assets/img/homes/home-1.jpg" alt="">
{% endfor %} <div class="card-img-overlay">
<h2>
{% else %} <span class="badge badge-secondary text-
<div class="col-md-12"> white">{{listing.prize}}</span>
<p>No listings available</p> </h2>
</div>
</div>
<div class="card-body">
{% endif %} <div class="listing-heading text-center">
</div> <h4 class="text-
primary">{{listing.address}}</h4>
<p>
Update few properties Dynamic listings of properties
<div class="row">
{% if propListings %}
{% for listing in propListings %}
<div class="col-md-6 col-lg-4 mb-4">
<div class="card listing-preview">
<img class="card-img-top" src="{{ listing.photo_main.url}}" alt="">
<div class="card-img-overlay">
<h2>
<span class="badge badge-secondary text-white"> {{ listing.prize}}
</span>
</h2>
</div>
<div class="card-body">
<div class="listing-heading text-center">
<h4 class="text-primary">{{ listing.title}}</h4>
<p>
<i class="fas fa-map-marker text-secondary"></i> {{ listing.address}}</p>
Lets put prize in correct format Dynamic listings of properties
Convert to
<a href="{% url 'listing' listing.id %}" class="btn btn-primary btn-block">More Info</a>
Home and About Dynamic part
Uptil now we had display home and about page with static content. Now lets move to
dynamic
Home.html (index.html) static code
{% extends 'base.html' %}
{% load static %}
{% block content %}
<section id="showcase">
</h1>
<p class="lead">This is the home page of real estate. You can search the properties based on your requirement like search with aminities, number of bedroom, state wise search etc</p>
<div class="search">
<form action="search.html">
<div class="form-row">
<label class="sr-only">Keywords</label>
</div>
<label class="sr-only">City</label>
</div>
<label class="sr-only">State</label>
{% load static %}
{% block content %}
<div class="container">
<div class="col-md-12">
</div>
</div>
</div>
</section>
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
</li>
</ol>
</nav>
</div>
</section>
def index(request):
return render(request,'pages/index.html')
def about(request):
#return HttpResponse('Hello, I am in About!')
return render(request,'pages/about.html')
Index page dynamic
pages/views.py
<div class="container">
<div class="row">
{% if homePropListings %}
<div class="card-img-overlay">
<h2>
</h2>
</div>
<div class="card-body">
<p>
<i class="fas fa-map-marker text-secondary"></i> {{ singleProp.address }} , {{ singleProp.city }}, {{ singleProp.state }}, {{ singleProp.zipcode }}</p>
</div>
<hr>
<div class="col-6">
<div class="col-6">
</div>
<div class="col-6">
<div class="col-6">
</div>
Output index html
Now we have latest 3 listing order by date in home page
About us page dynamic
Task : Up till now we displayed realter info (Our team) and seller of the month as static
content. Now make it dynamic.
About page views.py dynamic
Retrieve the realtors information and best player of the month from DB and pass it to
about.html page
pages/views.py
def about(request):
#return HttpResponse('Hello, I am in About!')
#Get all realtors
allRealtors = Realtor.objects.order_by('-hire_date')
context = {
'allRealtors' : allRealtors,
'mvp_realtors' : mvp_realtors
}
return render(request,'pages/about.html',context)
templates/pages/about.html About page html dynamic
{% extends 'base.html' %}
{% load static %}
{% block content %}
<section id="showcase-inner" class="py-5 text-white">
<div class="container">
<div class="row text-center">
<div class="col-md-12">
<h1 class="display-4">About Real Estate</h1>
<p class="lead">Welcome to Django real estate app</p>
</div>
</div>
</div>
</section>
# accounts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('login', views.login, name='login'),
path('register', views.register, name='register'),
path('logout', views.logout, name='logout'),
path('dashboard', views.dashboard, name='dashboard'),
]
Register and login views
Define methods in views.py
def register(request):
return render(request,'accounts/register.html')
def login(request):
return render(request,'accounts/login.html')
def logout(request):
return redirect('index')
def dashboard(request):
return render(request,'accounts/dashboard.html')
Open settings.py and add entry of the app 'accounts' Accounts app settings
INSTALLED_APPS = [
'listings.apps.ListingsConfig',
'accounts.apps.AccountsConfig',
'realtors.apps.RealtorsConfig',
….
]
urlpatterns = [
path('', include('pages.urls')),
path('listings/', include('listings.urls')),
path('accounts/', include('accounts.urls')),
path('admin/', admin.site.urls),
]
Now update/verify register and login link
Register and login links
base.html
def register(request):
if request.method == 'POST':
print("Submitted reg page")
return redirect('register')
else:
return render(request,'accounts/register.html')
#fill register form and sumit it. output of print will be displayed on command line
# Apply same thing for registration
Partials
Base.html code usually gets messy with html,bootstrap,css code. Partials
• Create separate folder called partials and divide the base page into different pages likes navbar, topbar etc.
Partial file convention is _filename,html
• Cut the code the topbar,navbar, footer from base.html to these files.
• Add load static into each partial file
{% load static %}
• Modify base.html – add include statements.
<!-- top bar -->
{% include 'partials/_topbar.html' %}
</body> </html>
Django Message framework
https://docs.djangoproject.com/en/3.1/ref/contrib/messages/
Quite commonly in web applications, you need to display a one-time notification message
(also known as “flash message”) to the user after processing a form or some other types of
user input.
For this, Django provides full support for cookie- and session-based messaging, for both
anonymous and authenticated users. The messages framework allows you to temporarily
store messages in one request and retrieve them for display in a subsequent request (usually
the next one). Every message is tagged with a specific level that determines its priority (e.g.,
info, warning, or error).
Update settings.py with message framework configuration
• Go at the end of file and add below configuration.
• Message app is default app and you can see entry in Installed_app array
'django.contrib.messages',
# Lets write alert message in separate file
# templates/partial/_alert.html
alert.html file
{% if messages %}
{% for message in messages %}
<div id="message" class="container">
<div class="alert alert={{ message.tags }} alert-dismissible text-center" role="alert">
<button type="button" class="close" data-dismiss="alert"><span aria-
hidden="true">×</span></button>
<strong>
{% if message.level == DEFAILT_MESSAGE_LEVELS_ERROR %}
Error
{% else %}
{{ message.tags|title }}
{% endif %}
</strong>
{{ message }}
</div>
</div>
{% endfor %}
{% endif %}
Update views.py
Update view.py code, send dummy message as of now
def register(request):
if request.method == 'POST':
print("Submitted reg page")
messages.error(request,"Testing error message")
return redirect('register')
else:
return render(request,'accounts/register.html')
Update register.html
Display the error message somewhere in register page
<div class="card-body">
<!-- Alerts -->
{% include 'partials/_alert.html' %}
<form action="{% url 'register' %}" method="POST">
{% csrf_token %}
Registration
Write basic code to validate if username exists in DB already, password/confirm pass do not
match etc.
For sample test create one user in DB from admin app
Lets work on registration code – accounts/view.py Registration
function – register
# Password match
if(password1==password2):
from django.shortcuts import render,redirect # Check Username
from django.contrib import messages if User.objects.filter(username=username).exists():
messages.error(request,'The username is not
from django.contrib.auth.models import User
available')
def register(request): return redirect('register')
if request.method == 'POST': else:
# Get form values if User.objects.filter(email=email).exists():
messages.error(request,'The Email
#first_name=request.POST['first_name']
ID is not available')
#last_name=request.POST['last_name'] return redirect('register')
username=request.POST['username'] else:
email=request.POST['email'] #Good to go
return
password1=request.POST['password1']
else:
password2=request.POST['password2'] messages.error(request,'Password do not match')
return redirect("register")
else:
return render(request,'accounts/register.html')
Test the registration code
Save the user registered user into DB
Its time to save the use details into DB and redirect the page to login.
else:
if User.objects.filter(email=email).exists():
messages.error(request,'The Email ID is not available')
return redirect('register')
else:
# Looks good, data entered by user is valid
user = User.objects.create_user(username=username,password=password1,
email=email)
user.save()
messages.success(request,"You are now registered and can login")
return redirect('login')
After user successfully registered
{% extends 'base.html'%}
{% block content %}
Update dashboard html code
<section id="showcase-inner" class="py-5 text-white">
<section id="dashboard" class="py-4">
<div class="container">
<div class="container">
<div class="row text-center"> <div class="row">
<div class="col-md-12">
<div class="col-md-12">
<h1 class="display-4">Dashboard- Real Estate</h1>
</section>
<table class="table">
<thead>
<!-- Breadcrumb --> <tr>
<section id="bc" class="mt-3">
<th scope="col">#</th>
<div class="container">
<nav aria-label="breadcrumb">
<th scope="col">Property</th>
<ol class="breadcrumb"> <th></th>
<li class="breadcrumb-item">
</tr>
<a href="index.html">
</div>
<td>45, Hadapsar road</td>
</section> <td>
<a class="btn btn-light" href="#">View
Listing</a>
If user is logged in then we have to show logout link otherwise register and login link should be displayed. Update navbar
<ul class="navbar-nav ml-auto">
{% if user.is_authenticated %}
login authentication check worked.
{% else %}
<li {% if 'register' in request.path %} class="nav-item active mr-3"
{% else %} class="nav-item mr-3"
{% endif %}
>
<a class="nav-link" href="{% url 'register' %}">
<i class="fas fa-user-plus"></i> Register</a>
</li>
<li {% if 'login' in request.path %} class="nav-item active mr-3"
{% else %} class="nav-item mr-3"
{% endif %}
>
<a class="nav-link" href="{% url 'login' %}">
<i class="fas fa-sign-in-alt"></i> Login</a>
</li>
{% endif %}
</ul>
Logout
We cant just add logout link and use it as get request.
We have to submit a form so that we can handle the logout and perform the logout with
POST.
{% if user.is_authenticated %}
# Some message
# Display the dashboard menu like welcome message and logout link
{% else %}
Display welcome message once logged in. Logout continue
<ul class="navbar-nav ml-auto">
{% if user.is_authenticated %}
<li
{% if 'dashboard' in request.path %}
class="nav-item active mr-3"
{% else %}
class="nav-item mr-3"
{% endif %}
>
Welcome {{user.username}}
<a class=nav-link href="{% url 'dashboard' %}"> Dashboard
</a>
</li>
{% else %}
<li
{% if 'register' in request.path %}
<ul class="navbar-nav ml-auto">
{% if user.is_authenticated %}
Logout link
<li
{% if 'dashboard' in request.path %} class="nav-item active mr-3"
{% else %} class="nav-item mr-3"
{% endif %}
>
<a class=nav-link href="{% url 'dashboard' %}"> Welcome {{user.username}} Dashboard </a>
</li>
<li class="nav-item mr-3">
<a href="javascript:{document.getElementById('logout').submit()}"class="nav-link">
<i class="fas fa-sign-out-alt"></i>logout
</a>
<form action="{% url 'logout'%}" method="POST" id="logout">
{% csrf_token %}
<input type="hidden">
</form>
</li>
{% else %}
Logout code
accounts/views.py
def logout(request):
if request.method == 'POST':
auth.logout(request)
return redirect('index')
Contacts
- Create new app Contacts app
$python manage.py startapp contacts
C:\Users\kunalpag\Documents\My_data\python-proj\django\helloworld>python manage.py
migrate contacts
Operations to perform:
Apply all migrations: contacts
Running migrations:
Applying contacts.0001_initial... OK
Django errors and resolution
How To Add New Model Field To Exist Django Model
1. Change Django Model Field Steps.
Change model class field in Django application models.py file. Below example add a new field user_desc =
models.CharField(max_length=100, default=”), and remove field emp_onboard_date =
models.DateTimeField(auto_now=True).
2. Better specify a default value for the new field, otherwise you may encounter below error message
when you make migrations.
$ python3 manage.py makemigrations dept_emp
You are trying to add a non-nullable field ' user_desc ' to employee without a default; we can't do that
(the database needs something to populate existing rows).
Please select a fix:
• 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
• 2) Quit, and let me add a default in models.py
Select an option:
How To Add New Model Field To Exist Django Model
If you want to remove all the model related talbes in the backend. Remove it from backend using mysql.
Run
$ python3 manage.py makemigrations dept_emp
$ python3 manage.py migrate dept_emp zero
But during above process, you may encounter error message like django.db.utils.IntegrityError: NOT NULL
constraint failed: dept_emp_employee.dept_id.
To resolve above error, you need to delete all the past migration generated python files in
the dept_emp / migrations folder, but do not remove the 0001_initial.py file.
Then again run
$ python3 manage.py makemigrations dept_emp
$ python3 manage.py migrate dept_emp zero
Help:https://www.dev2qa.com/how-to-drop-change-tables-from-sqlite3-database-in-django/
Django hosting
Create account on
https://www.pythonanywhere.com/user/kunalkp6/