Python / Django Flashcards
Python console I/O
Input:
def input(“String appears to prompt user to input”)
This function returns string from what user type
Output:
def print(“What to show in console”)
Python type casting
Cast to int: int( / some string for float etc / )
Python conditional statement
if boolean_expression: some expression elif another_boolean_expression: some expression else: some expression
Python sequence type
Python provides different array-like data structure for handling multiple related element with different feature: string, list, set, tuple, dict (key : value)
Mutable / Immutable sequence: whether the sequence or the sequence’s element can be modified, (ex: add element to sequence, change value in particular index)
Ordered / Unordered: whether swaping two position inside a sequence create a new sequence or it is still considered the same one
Some sequences have supported function, syntax:
vector.sort()
all_sequence.len()
Python lists
Ordered: Yes Mutable: Yes Syntax: names = ["Harry", "Ron", "Hermione"] Lists behave similar to C++ vector, can insert / append / remove elements, swap elements create a new python lists, elements can be modified. Can contains multiple similar elements. Supported function: append() insert() operator[] sort()
Python tuples
Ordered: Yes
Mutable: No
Syntax: point = (1.3, 4.2, 0.1)
Tuples behave like constant list, order matters and can contain multiple similar element, but when created cannot be modified anymore.
Python set
Ordered: No Mutable: Yes Set only store each value once, if add multiple simlar value, set only display that value once and ignore the others Syntax: sign = set() / create empty set / Support function: set.add(5) set.add(4) set.add(3) print(set) --- > {5, 4, 3} set.remove(4)
Python dict
Ordered: No
Mutable: Yes
Dictionary is Set of < Key : Value > pairs, each key in dictionary has corresponding value.
Syntax:
info = {
“name” : “Harry”,
“age” : 19,
“school” : “Hogwarts” / last one doesn’t need semi colon /
}
Support function:
Adding Key-Value: info[“degree”] = “bachelor”
Access value through key from dictionary:
print(info[“name”]) — > Harry
Python loops
Element wise loop
names = [“Harry”, “Ron”, “Hermione”]
for name in names:
print(name)
for char in “Harry”:
print(char)
Range loop
for i in range(6): / Loop from 0 to 6 - 1 /
print(i)
Python function and modules
Function defined in function.py def func(parameter): some statement return value In main.py to use function func, have 2 option name = "Harry" 1) from function import func print(func(name)) 2) import function print(function.func(name))
Python Object-Oriented Programming
Create User-defined class having attribute and behaviour method. Ex: class Flight(): / self is reference to that particular instance, not including self means static function (represent for whole class) cannot access to that instance attribute / def \_\_init\_\_(self, id, from, to, capacity): self.id = id self.from = from self.to = to self.capacity = 100 self.passengers = []
def add_passenger(self, passenger) if not seat_available(): return False else: self.passengers.append(passenger) return True
def seat_available(self): return self.capacity - len(self.passengers)
# Create a new flight with o=up to 3 passengers flight = Flight(3)
# Create a list of people people = ["Harry", "Ron", "Hermione", "Ginny"]
Attempt to add each person in the list to a flight
for person in people:
if flight.add_passenger(person):
print(f”Added {person} to flight successfully”)
else:
print(f”No available seats for {person}”)
""" Output: Added Harry to flight successfully Added Ron to flight successfully Added Hermione to flight successfully No available seats for Ginny """
Python Functional Programming
Decorator: function receive a function parameter, return a wrapper function, adding some preprocess and postprocess code for original function. Example: def fun(name): return f"Hello, {name}!"
def checking(name): def wrapper(name): if is_alpha(name): print(fun(name)) else: print("Invalid name, no hello") return wrapper
name = input(“Name: “)
/ decorator means running the modified version return from “checking” function /
@checking
fun(name)
Lambda function: short notation for input variable and return some element or modification of input. Syntax: square = lambda x : x * x Example: Nesting dicts inside a list people = [ {name: "Harry", house: "Gryffindor"}, {name: "Cho", house: "Ravenclaw"}, {name: "Draco", house: "Slytherin"}, ] Cannot use people.sort() since " operator < " not defined between dict and dict. Have to pass in function as variable for sort() to figure out the order.
name.sort(key = lambda person : person[“name”])
sort() will traverse whole list with the function from key parameter to get keys and sorting on those keys
Django
Python framework providing modules and feature helping ease the process of writing fully-fledge dynamics web applications by handling all the protocol and building blocks that every type of web applications does so that the programmers can focus on the intersting logic of building their web apps – > improve productivity
HTTP protocol
The protocol that defined has standard method for communication between clients and server by sending message for verification and routing then receive the demanded package from the server. An structure of the typical HTTP protocol signal:
From client: / GET is one type of HTTP message beside POST 1.1 is the HTTP version, host will be the URL client trying to access to/ GET / HTTP / 1.1 Host: www.example.com Server respond: HTTP / 1.1 200 OK Content-type: text / html
/ The 200 code means the GET process works well, no error happening, and the server respond with the right package in the type of html pages that the client browser will render to display /
Some prevalent HTTP protocol code
200: OK
301: Move page permantly
403: Access denied
404: Not found
500: Internet Server Error, the web applications having bugs so the programmer have to dive in and fix it
Starting Django project
Django project must be created and deploy inside an Python Virtual Machines for servering with localhost:
mkvirtual VM-names
Command for starting to create Django apps:
“django-admin startproject PROJECT_NAME”
Starting Django application
Django project contains multiple Django applications. Process for creating application inside Django projects:
- Create application folder in terminal: python manage.py startapp app-name
- Add newly created application into Django project:
In setting.py find list named INSTALLED_APPS from which Django decides what apps has been installed on this projects, and add ‘app-name’ to that list
Django application views
Each Django application’s folder contains views.py module handle what to display to user when visiting particular URL route. Typical functions / modules written in views.py:
from django.http import HttpResponse
def index (request): / request: Objects represent the
return HttpResponse(“Hello, world”) HTTP request user use to access
this web server of which attributes
contain all info about the request /
To define when this response actually be triggered – > define a specific URL route associate with this views.index modules.
Django URL route
In Django projects root folder and each Django application’s folder contains urls.py modules, handling the URL routing process by a pyramid system:
1) Django projects urls.py is the root of urls.py routing tree, contains the prefix part of the URL name deciding which applications to go inside the project. The typical root urls.py:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path(“admin / “,include(“admin.site.urls”),
path(“hello / “, include(“hello.urls”))
]
/ urlpatterns is python lists sequence contains all the URL path can be attached to move to some particular application by accessing that appliction’s urls.py module /
“hello / “: The URL link appears in the brower search bar
include() function access the given module (access hello folder then dive into its urls.py file) then traverse through the urlpatterns list to get the demand urls path.
2) Django application urls.py considered as the child, continue to search with the remaining part of the URLs for finding the right Http Response. The typcial application urls.py:
from django.urls import include, path
from . import views
urlpatterns = [
path(“”, views.index, name=”index”),
path(“ < str:name > “, views.greet, name=”greet”)
]
/ The views.py and urls.py contained in same folder, use “from . import” /
“”: The prefix path “ / hello” had been handled by the root urls.py this application’s urls.py just have to extending the path
The name parameter in path() make it easy to reference to this URL path from other parts of application, preventing hard coding the URL
< str:name > : convertible URL by parameterize the path. In views.greet respond:
/ the name parameter have the string values convert from < str:name > in the URLs; hence the same “name” /
def greet (request, name):
print(“Hello, {name.capitalize}”)
Searching 127.0.0.1:8000/hello/thinh – > Hello, Thinh
“thinh” passed into greet function as variable name
Django Templates
Instead response with string, response with .html file. In views.py:
from django.http import HttpResponse, render def greet (request, name): / name variable taken from < str:name > in URLs return render (request, "hello / greet.html", { / context dictionary for html templates / "name": name.capitalize, })
“name” will be variable passing into greet.html file with the value name.capitalize
In hello folder create templates folder create hello folder inside that then greet.html, reason for templates / hello / greet.html is preventing conflict between apps having same .html names
In greet.html:
< head > < title > Name < / title > / Double curly braces for context variable / < / head > < body > < h1 > Hello, {{ name }} < / h1 > < / body >
Django templates conditional logic
Inside views.py: import datetime def index (request): now = datetime.datetime.now return render(request, "newyear / index.html", { "new_year": now.date == 1 and now.month == 1, / Django paradigm: dictionary key will be the variable django templates be able to access to when render the HTML templates, dictionary value will be python variable value passing to templates / })
In: / templates / newyear / index.html < head > < title > Is it New Year < / title > < / head > < body > {% if new_year %} < h1 > YES < / h1 > {% else %} < h1 > NO < / h1 > {% endif %} < / body >
Django static files
In newyear folder application create static folder, inside that create newyear folder then styles.css
In templates / newyear / index.html, to include CSS file: {% load static %} < head > < title > Is it New Year < / title > < link href={% static "newyear / styles.css" %} / Avoid hard coding to css destination / "rel"=stylesheet > < / head > < body > {% if new_year %} < h1 > YES < / h1 > {% else %} < h1 > NO < / h1 > {% endif %} < / body >
Django templates loops
Create tasks application: 1) Terminal 2) Add application name to In views.py: tasks = ["bar", "boo", "baz"] def index (request): return render(request, "tasks / index.html", { "tasks" : tasks, })
In templates / tasks / index.html {% load static %} < head > < title > Todo Lists < / title > < link href={% static "tasks / styles.css" %} "rel"=stylesheet > < / head > < body > {% for task in tasks %} < li > {{ task }} < / li > {% empty %} / In case of empty tasks / < li > No tasks < / li > {% endfor %} < / body >
Django templates inheritance
Each Django applications templates folder tends to have multiple .html templates file that have the same structure. For example: the layout of the pages, the link to same styling file, same heading, etc.
If all the the .html files that intented to have the same layout was hard coding, when demands for modified the layouts of the web pages appears, all the html files have to be edited one by one, causing unefficiency.
So the ability to factor out the HTML code that all pages having in common is helpful design, comes in Django templates inheritance feature. Syntax:
For example having to file index.html for saving tasks and add.html for input new task to html form with the same layout, same styling, create an parents .html file for the layout layout.html:
{% load static %}
< head >
< title > Todo Lists < / title >
< link href={% static “tasks / styles.css” %} “rel”=stylesheet >
< / head >
< body >
Syntax
{% block body %} / body: user-chosen block’s name /
{% endblock %}
< / body >
The block body inside layout.html can be edited by all the files inherit from it.
In index.html extending layout.html: *Syntax* {% extends "tasks / layout.html " %} {% block body %} / The same code inside the layout.html file / < ul > {% for task in tasks %} < li > {{ task }} < / li > {% endfor %} < / ul > {% endblock %}
In task.html extending layout.html: {% extends "tasks / layout.html " %} {% block body %} / The same code inside the layout.html file / < form > < input type="text" name="task" > < input type="submit" > < / form > {% endblock %}
Django templates URL referencing by name given to that URL route
Remind in urls.py:
urlpatterns = [
path(“ / add”, views.add , name=”reference_name”),
]
In Django projects there some demands for changing between URLs triggering different views function by clicking the URLs link given the pages.
In task application, index.html links to add.html:
< a href=”task/add/” > Add new task < / a>
The url above was hard coding, demands changing the urls path only satisfied by both changing the urls in the path() function in urls.py and changing all urls in all html templates links < a > refering to that particular url.
Using the string given for name attribute given for each path in urls.py to refer to route without the risks of having to finding that spot to edit again
* Syntax *
< a href = “{% url ‘add’ %}” > Add new tasks < / a >
Whenever the urls route is edited inside path() in urls.py, Django will automatically figure out what the new urls path should be in all the html url links.
Django namespace collision URLs routes giving the same name / Demands for jumpings to URLs of different Django applications inside the project
Inside Django projects, many Django application occasionally given the same specific name for its specific route, the most popular one is name=”index”. Example
Inside newyear / urls.py:
path(“”, views.index, name = “index”)
Inside tasks / urls.py:
path(“show / “, views.show, name = “index”)
There are some specific demands to specifiy of which Django application “index” url to go newyear or task. Solution is specify above an global variable called app_name, example in task/urls.py:
app_name = tasks
urlpatterns = [ … ]
Link from every web apps to specific “index” urls in the “tasks” application
* Syntax *
< a href = “{% url ‘tasks:index’ %} > Add new tasks < / a >
Another link to newyear application “index” url
< a href = “{% url ‘newyear:index’ %} > Add new tasks < / a >
Django HTML templates form
< form action = “{% url ‘tasks:add’ %}” method=”post” > < / form >
method = “post” – > Announcing the type of HTTP request is POST
HTTP Post request method uses for changing modifying some inner state of the server mostly database.
The default HTTP request type when typings URLs on search bar or clicking hypertext changing between web pages or web application is called GET method, tends to include parameter inside the URLs string for more access info, for instance: google.com with as_q, lr, cr parameter, while POST request doesn’t
Django paradigm of Web Form
An URLs route having ability to modify changes usually receive two different types of HTTP requests: GET and POST and will behaves differently for each types of request defined by functions inside views.py:
Checking HTTP types with request parameter
GET: respond with render HTML pages with form
POST: conduct some inner database server process written inside views.function update info, then change to GET request by HTTP redirect to URLs to other web pages or web applications
Cross-site request forgery
An security issue that strangers from their own website can forge HTTP POST request to our own server causing unexpected dangerous modification in database, state of web server.
Solution:
< form action = “{% url ‘tasks:add’ %}” method=”post” > < / form >
{% csrf_token %}
< / form >
Django has CSRF checking turn on by default with CSRF Middleware in settings.py. Adding csrf_token to HTML forms, the form given to user with GET request accompanied by an hidden input tag:
< input type=”hidden” name=”csrfmiddlewaretoken” value=”hashcode” >
When user submit with POST request, server first check does the csrf-token “hashcode” matched with the one server sends to that session the user currently in, only then accept to follow the POST request
Django forms.Form predefine standard HTML form
Forms is popular HTML components with its input frequently modified over time. Insteading of having hard coding the input field inside all HTML forms, Django supports creating user-defined class for handle input field baking in the HTML forms. Updating forms only requires to edit the Python code inside Django class in views.py created form those form, then Django automatically update all necessary form.
Creating user-defined class to represent all the fields of HTML forms inheriting univeral form feature predefined in Django forms.Form class. In views.py:
from django import forms
class NewTaskForm (forms.Form): / inherit Python class put in parenthese /
task = forms.CharField (label = “New Task”)
priority = forms.IntegerField (label = “Priority”, id = “pr”)
“task” is the reference names for getting the value in views.py stored in paramter request.POST[“task”] when user sends the POST request
def add (request):
return render(request, “tasks / add.html”, {
“form”: NewTaskForm(), / form as an value /
}
In templates / tasks / add.html:
< form action = “{% url ‘tasks:add’ %}” method=”post” > < / form >
{% csrf_token %}
{{ form }}
< / form >
Django server-side HTTP request validation process
In views.py: from django import forms from django.http import HttpResponseRedirect from django.urls import reverse class NewTaskForm (forms.Form): task = forms.CharField (label = "New Task") priority = forms.IntegerField (label = "Priority", min_value=1, max_value = 10)
def add(request):
if request.method == “POST”:
form = NewTaskForm(request.POST)
/ populate form request.POST which contain all the data the user submitted when submitting the fomr/
if form.is_valid():
task = form.cleaned_data[“task”]
tasks.append(task)
return HttpResponseRedirect(reverse(“tasks:index”))
/ Instead of hard coding URLs route for redirection, use reverse method for Django to automatically figures out the URLs route, with the same string type in templates /
else:
return render(request, “tasks / add.html”,{
“form”: form / Not NewTaskForm() /
/ send back the same form that user submited instead, Django also help display the error automatically by some predefine function /
}
else: / GET request /
return return render(request, “tasks / add.html”,{
“form”: NewTaskForm()
}
Above views function is common paradigm in Django, where web pages provide user form via GET request, user fill in the form and submit via POST request to some URLs route to trigger the function in views.py to handle the modification request then redirect to other URLs route to display the results, all handle in one or couples of views.py’s function.
Django Session
Session is dictionary storing info of clients, in the context of simple Django Web programming, session work as way for server to identify where the request sent from base on primary key “session_id” in Session dictionary accompanying the HTTP request (session accessed in request.session), session_id usually identify specifically for cookies saving on PC browser. Open browser with different session (reset cookies or icognito mode) will receive different state of communcation or data if those info are depends on the session_id.
Server saved a list of session for matching caching purpose.
Example of storing data into default-like session database:
In views.py
def index(request):
if “tasks” not in request.session:
request.session[“tasks”] = []
return render(request, “tasks / index.html”, {
tasks: request.session[“tasks”],
}
def add(request):
if request.method == “POST”:
form = NewTaskForm(request.POST)
/ populate form request.POST which contain all the data the user submitted when submitting the fomr/
if form.is_valid():
task = form.cleaned_data[“task”]
request.session[“tasks”] += [task] / Concatenate two lists /
return HttpResponseRedirect(reverse(“tasks:index”))