Django Workshop
🚀

Django Workshop

Tags
Web Dev
Workshop
Python
Published
Published July 17, 2022
Author
Qiu Weihong

Web Development

Backend development
The backend or server-side of the website takes care of data storage and management. It sends and receives data from the front-end side of the website and process it such that the front-end display the desired information.
Eg: Login page
  • input username and password at the front-end
  • This data is packaged and sent to the backend
  • The backend scripts validates the data
  • If the username and password is correct
  • That specific user's information is sent to the front-end
  • Front-end then takes in all these information and render the specific user's page

Django

Why Django?
  • Its based on python
  • Simple syntax
  • Its own web server
  • MVC (Model-View-Controller) core architecture
Let's get started!

Open up terminal in your machine

  • Command Prompt or Anaconda Prompt for windows user
  • Create a folder in the desired place that you wish to store this project
  • You can create the folder using mkdir folder_name or just right click and create new folder
  • use cd path/to/your/folder to get to the folder

Create an virtual environment

This is for better package management
python3 -m venv env or python -m venv env
On Windows, run:
env\Scripts\activate.bat
On Unix or MacOS, run:
source env/bin/activate

installing the packages we need

pip install Django==3.1.4

Get started with the actual project

start a new django project
django-admin startproject first_django
get into the project folder by:
cd first_django
You shold see another first_django folder with a mange.py file
Now run python mange.py runserver
It should give you a url for you to go to. Open your webbrowser, key in the url and this is what you should see.
notion image
notion image

Use of a text editor

  • Here are some of the recommendations
Open the folder using the text editor

Settings.py

This is the fundamental configurations of your django project
BASE_DIR gives directory to this django project
SECRET_KEYis the unique key for your django project, protect it well because it may lead to security flaws
DEBUG It is a useful feature when you are in the developing phase, change it to false when you are ready to deploy the website
ALLOWED_HOSTSStore all the domain name allowed to use the project.
INSTALLED_APPSThis holds the names of all Django applications that are activated in this Django instance. Apps can be used in multiple projects, and you can package and distribute them for use by others in their projects.
MIDDLEWARE This is all the security features and how your requests of the website is handled
ROOT_URLCONF This is to tell the django project how to route your website
TEMPLATES This is where the html templates that django is going to render
WSGI_APPLICATION This is how your server works and sometimes you will need to change it sometimes you dont
DATABASES This is the database that django project used. By default is sqlite3.

Let's start play with it!

Run python manage.py migrate in your terminal.
This commnand checks through you installed apps and create the necesary database tables
Then run python mange.py createsupreuser to create a super user to login to the admin page
Run python mange.py runserver
Key in the username and password that you have just now and you will get into the admin page

Create your first app

It is not the app on your phone but more like a component or functionality of your django project
In your terminal, make sure that you are in the project folder which contains the mange.py file.
Run python manage.py startapp your_app_name
Let's say in this case, I want to build an ecommerce platform. I will run python manage.py startapp products
You will now see that a new folder with the name of your app is created
You can create multiple apps, but one app should be dedicated to one function and do that function really well.

Creating models

Models contains the essential fields and behaviors of the data that you are storing.
In your app folder, you will see a models.py
In models.py, I will create a new class called Product which stores all the essential data that a product should have.
The Code below and fieldtypes are just an example.
More field types can be found here
If you want to add more fields afterwards. makemigrations will sync the database with the model that you have but for older records in the database without these new fields you will need a default value for the older records
#This is your models.py from django.db import models class Product(models.Model): title = models.CharField(max_length=120) description = models.TextField() price = models.DecimalField(decimal_places=2,max_digits=10000)

'Install' your app

After creating the models for your app
You can add your app to the project by going to the settings.py
In the INSTALLED_APPS add your app name to it.
Save all your edited files.
In the terminal, run python manage.py makemigrations
Then, python manage.py migrate
You should run these two commands together every time you make changes to your models.py
makemigration checks and updates the changes that you have made to the model, while migrate takes these changes and updates the database format
#Your settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'product', ]

Registering the model with admin

In order to view your model in the admin site.
Go to the admin.py file under the app folder
Import the model that you have made and register it
After registering, run python manage.py runserver and go to the admin site and you should see your newly created models there
#Your admin.py from django.contrib import admin from .models import Product admin.site.register(Product)

Adding deleting and formatting Data

If you want to add data to the database
You can create the data base record using Product.objects.create(title='',des = '',price =0.0) In the django shell
You can open django shell in terminal using python manage.py shell
You can also write a class method to add data.
After you have the code below in your models.py, you can open up django shell.
Enter from products.models import Product to import the model
Then call the class function by Product._create_data() to create the data automatically.
#Your updated models.py class Product(models.Model): title = models.CharField(max_length=120) description = models.TextField() price = models.DecimalField(decimal_places=2,max_digits=100) def __str__(self):#This function changes how the data is presented. You change view the change when you see it in the admin site return '{}{}'.format(title,price) @classmethod def _delete_data(cls):#this function deletes all the data Product.objects.all().delete() @classmethod def _create_data(cls,count = 1000): for i in range (count): Product.objects.create(title='title'+str(i),description = 'This is the description for title'+str(i),price=count)

Creating the first webpage

For websites, we definitely need a lot of different pages for users to go to.
  • profile
  • home
  • social
  • contact
How do we do that?
we render these pages in the views.py of your app.
In your views.py you should define a function of how the specific page should be rendered.
# This is your models.py from django.shortcuts import render from django.http import HttpResponse # Create your views here. def home_screen(request): return HttpResponse('<h1>Hello World</h1') def contact_page(request): return HttpResponse('<h1>This is the contact page</h1>')

After you have define the function, you need to go to the urls.py in you project folder.
This urls.py takes care of all the requests and routing of the webiste.
Import your home_screen and contact_page function that you have defined earlier into this urls.py
define the url path and call the function
Now go to home and contact page to take a look (remember to run the server before you go to the webpage)
#This is your urls.py from django.contrib import admin from django.urls import path from products.views import home_screen,contact_page urlpatterns = [ path('',home_screen), path('contact/',contact_page), path('admin/', admin.site.urls), ]

Django Templating engine

You would not want to return entire webpage as an http response.
We can make use of the Django Templating Engine to help us render a html out as a response to the http request
In order to do that, we use the render function that is already imported for you by default in the views.py
The following code will explain to you how to use it
from django.shortcuts import render def home_screen(request): return render(request,'home.html',{})

Explanation

All in all you just have to return the render function with the 3 parameters.
The request that is past by the urls.py, the 'home.html' which is the html template that you wish to output. Lastly, a dictionary, containing the data that you want to pass to the html to be rendered.
The ability to pass data to html page to be rendered is essentially what makes the templating interesting. You just need a general design of the website and just fill the blanks in with data.
Where do we put the html templates?
Create a templates folder in the root directory of the django project. And then dump all your templates that you want to use inside.
For Django to know where this folder is, go back the the settings.py and add os.path.join(BASE_DIR,'templates') in your DIRS list under the TEMPLATES

How should you write your html

Because we want to render data using django, we cannot just write the html like how we usually do.
When we want to access the key and value pair in the dictionary we just simply use {{key}}
If the value is a list then we can use a for loop to loop through the content in the list and display them
There django also allow you to use if else statement to perform condition checks.
More about the django template tags can be found here
#This is your views.py def home_screen(request): data = { #This is the setof data that i want to pass to the html page 'user':'qiuweihong', 'age':21, 'telegram':'@iceridge', 'myfifthrow':['3dc','badminton','photog'] } return render(request,'home.html',data)
#This is your home.html <h1>Hello Word</h1> <p>This is {{user}}</p> <p>I am {{age}} years old</p> <p>My telegram is {{telegram}}</p> My Fifth Rows are: <ul> {% for fifthrow in myfifthrow%} {%if fifthrow == "3dc" %} <li style="font-weight:bold;">{{fifthrow}}</li> {%else%} <li>{{fifthrow}}</li> {% endif %} {%endfor%} </ul>

Getting data from the data base

Now we are still hard coding the data, but for backend we wannt to make full use of the data base
What we need to do:
  • Import the data into our views.py
  • Use query set to search for the data in the database
  • put into the dictionary to be pass to the front end to be rendered.
How to use the querysets can be found here
#Your views.py from django.shortcuts import render from django.http import HttpResponse from .models import Product #importing the data # Create your views here. def home_screen(request): info = Product.objects.filter(title='title992')[0] #query the object from your database, rember to create the data first data = { #adding the result to the data dictionary and pass to front-end 'title':info.title, 'description':info.description, 'price':info.price } return render(request,'home.html',data)

How to pass data from front-end to backend

In order for the website to be responsive, not only does the backend need to pass data to frontend but the frontend also have to pss data to backend.
Two commonly used methods:
  • Include the query data in your url query string
  • Post request

Include the query data in your url query string

If you take a look at some of the urls you will see that there is a component that starts with '?' and then followed by a bunch of key and value pair
Those are the data that are past to the backend. Hence in our html page, we can simply include an a tag to send the data to the backend
For the backend, to receive the data we can use request.GET.get(data_you_want_in_the_query_string,'none')
request.GET give a dictionary like object of the get parameter
<h1> THis is your product page</h1> <a href=?num={{num}}>next_product</a> <p>{{title}}</p> <p>{{description}}</p> <p>{{price}}</p>
def home_screen(request): num = request.GET.get('num','1') print(num) info = Product.objects.filter(title='title'+num)[0] data = { 'title':info.title, 'description':info.description, 'price':info.price, 'num':int(num)+1 } return render(request,'home.html',data)

Setting up an api and receive the data via post.

For the frontend side of how to make a post request, it will be taught in the react workshop tmr.
For now we will be using postman to simulate a post request from the from end.
from django.shortcuts import render from django.http import HttpResponse from .models import Product from django.views.decorators.csrf import csrf_exempt import json @csrf_exempt #this csrf_exempt is to bypass one of the security features that django has #do this only when you trust whoever who has access to the api and your api wont cost any irreversible damage #if not you will need to include an csrf token in your request def process_api(request): if request.method != 'POST': return HttpResponse('Error 403',status=403) request_title = request.POST.get('title') info = Product.objects.filter(title=request_title)[0] data = { 'title':info.title, 'description':info.description, 'price':float(info.price), } return HttpResponse(json.dumps(data),status = 200)
#remember to route your url to the api function from django.contrib import admin from django.urls import path from products.views import home_screen,contact_page,process_api urlpatterns = [ path('',home_screen), path('contact/',contact_page), path('admin/', admin.site.urls), path('api/product',process_api) ]

How to use postman

Postman is a very powerful tool when you want to do testing for your web applications
Launch the app from the chrome store, and sign up for an account and sign in.
If you dont want to sign up its fine too, just watch what I do.
Once you get into the interface, on the main window, change the GET to POST. and key in the api route that you have set up just now.
In this case it will be 127.0.0.1:8000/api and below it you will see a body section, click in and enter the key and value pairs that you wish to send to the backend.
The bottom section will show you the http response that the backend return, it the content is what you want then your api is working!

How to deploy the backend server with heroku

In your terminal, go to your project root folder, the one that contains the manage.py file.
Create a repo for it by running git init if you dont have git installed you can find the method here
Then you need to first stage the changes that you have made by running git add .
and commit the changes by git commit -m 'message for this commit'
Run heroku login to login to your heroku account.
Run heroku create to create a new heroku project under your account, by default the name will be given randomly, if you wish to have your own name, you can add it behind the create
When done creating, you will be given an url in the form of https://name-of-your-app.herokuapp.com and now what we want to do is to add a git remote to heroku
To do that we need to run heroku git:remote -a name-of-your-app
Now install a package call gunicorn by pip install gunicorn This is needed because when we use manage.py runserver, it is running on the development server, when we are deploying it we can no longer use it. We need a different app server which in this case gunicorn.
Run gunicorn first_django.wsgi
You should see the website running in the link given.
We now need to create a file called Procfile and store this command inside, this is to tell heroku what command to run
run touch Procfile and open it up using the text editor.
Then key in web:gunicorn first_django.wsgi
Now if you run heroku local, you are trying to run the project locally using heroku. You should get the same thing as how you have run it on the development server
Then run pip freeze ->requirments.txt to store all the package that you have installed for this project to the requirements.txt and heroku will use this to know what package to install.
Go to your settings.py and add STATIC_ROOT = os.path.join(BASE_DIR,'static')to get a directory for your static files such as css and js
Under the ALLOWED_HOST, add in the domain of your heroku app. Which is this name-of-your-app.herokuapp.com
Now push it to heroku by git add . then git commit -m 'message for this commit' and finally git push heroku master
HALF WAY THERE
Now we want to deal with the database. Because heroku delete all the files and restore it once in a while and the infomation in the database will be lost, so we need to store it in the cloud. We will be using postgresql which is provided by heroku.
First, install the dependency using pip install psycopg2
Then go to heroku home page in you web browser, click on this project. In the Settings tag, you will see Config Vars with a button Revel Config Vars at the side. Click on it, and then copy the value corresponding to the DATABASE_URL
It will be in this format:postgres://USERNAME:PASSWORD@HOST:PORT/NAME
In your settings.py change the DATABASE accordingly in this format.
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql',#change from the default sqlit3 to postgresql #fill in the values in your url string 'NAME': 'd46a3fm2pmo145', 'HOST':'ec2-52-203-49-58.compute-1.amazonaws.com', 'PORT':5432, 'USER':'wvoznxouhbeaqf', 'PASSWORD':'0cbbb979d4f4f1622408d92c2389c07cfa603d259005bd9bec20d497f8ffd858', } }
Run python manage.py migrate to migrate your existing models to your new database.
Note that your old data in your sqlite3 database wont be preservered so you will need to create another super user account using python manage.py createsuperuser and add data to the database if you need
LAST PART We will need to deal with the static files that we have for example the images, css and js files.
first we need to do python mange.py collectstatic which will help you collect all the static files you need for django admin site into on folder automatically. you can add your own static files to the diretory and use them in your templates by {%load static%} at the top of your template to 'import' the directory and then use {%static 'path/to/your/file'%}
Go to your urls.py and make the following changes
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ ... ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Now we need to serve the static images from the app server.
To do this we run pip install whitenoise
then add 'whitenoise.middleware.WhiteNoiseMiddleware', to your MIDDLEWARES under the settings.py
Then you want to update your requirments.txt by pip freeze ->requirments.txt
Now push it to heroku by git add . then git commit -m 'message for this commit' and finally git push heroku master
And when you click into the link given, you should see it running perfectly!!!

Conclusion

There are many possiblilties with django and I think yall definitly learn alot during this lesson and hopefull this workshop will help you out in your future projects!
Thank you for your time and if you have any questions feel free the message me and i will try my best to answer you!

References: