Django¶
Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.
Useful Links:
- https://www.w3schools.com/Python/default.asp
- https://docs.djangoproject.com/en/3.0/
- https://simpleisbetterthancomplex.com/
- https://wsvincent.com/
- https://books.agiliq.com/en/latest/README.html
- https://python.doctor/
Install Django¶
You need python and pip installed in your system
In Terminal
python --version
pip --version
pip install django
Start a project with Django¶
after you installed django, the django-admin command will be available, try to run your server
In Terminal
django-admin startproject project_name
cd project_name
python manage.py runserver 8000
Let’s look at project_name structure. there is only 2 important files here:
- settings.py : django project setting/configuration
- urls.py : the table of content, contain routes
Create application with Django¶
What’s the difference between a project and an app? An app is a Web application that does something – e.g., a Weblog system, a database of public records or a small poll app. A project is a collection of configuration and apps for a particular website. A project can contain multiple apps
In Terminal
python manage.py startapp app_name
Structure¶
those are the important files
app_name/ __init__.py admin.py apps.py migrations/ __init__.py models.py ---> our data persistance tests.py urls.py ---> where routes lives views.py ---> where views functions goes (controllers)
Configuration¶
after creating our app we must add it to the INSTALLED_APPS array in the settings.py of our project
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app_name', #<--------> add this ]
In Terminal
mkdir templates
# in settings.py # in TEMPLATES list # we must set the proprety DIRS like this 'DIRS': [os.path.join(BASE_DIR, 'templates')]
the best practices says : for every app we have: make sure to create a folder with the app_name under templates
views¶
django view can return 3 things HttpResponse, JsonResponse or a html page, lets create those 3 types
#in views.py of the application from django.http import HttpResponse, JsonResponse from django.shortcuts import render def example_http(request): return HttpResponse("hello from your example app") def example_http_with_param(request, id): return HttpResponse("hello from your example app with id = {}".format(id)) def example_json(request): data = [ {'id': 1, 'name': 'example1'}, {'id': 2, 'name': 'example2'} ] return JsonResponse(data, safe=False) def example_html(request): return render(request, 'exampleapp/example.html')
routes¶
to access your views you must add routes a route for eath view
#in urls.py of the application from django.urls import path from . import views app_name = 'exampleapp' urlpatterns = [ path('http/', views.example_http, name='http_example'), path('http/<int:id>/', views.example_http_with_param, name='http_example_with_param'), path('json/', views.example_json, name='json_example'), path('html/', views.example_html, name='html_example'), ]
until now our views are not accessible, we must plug the project routes with the application route.
#in urls.py of the project from django.urls import include # add this import path('example/', include('exampleapp.urls')), # add this line
Get your hands dirty with templates¶
Configuration¶
we must configure the static folder
# in settings.py STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR, "static"),] # in urls.py of the project from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # ... the rest of your URLconf goes here ... ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) #in templates {% load static %} <img src="{% static "my_app/example.jpg" %}" alt="My image">
Data and templates¶
we need to pass data to our template first
def example_html(request): dictionary = { 'display': True, 'students': [ {'fullname': 'flen ben flen 1', 'level': 1}, {'fullname': 'flen ben flen 2', 'level': 2}, {'fullname': 'flen ben flen 3', 'level': 3} ] } return render(request, 'exampleapp/example.html', dictionary)
then we can use it in the html
{% if display == True %} <ul> {% for student in students %} <li>{{ student.fullname }} - {{ student.level }}</li> {% endfor %} </ul> {% endif %}
paths in templates¶
to make links between pages we must use the routes already created
<a href="{% url 'app_name:route_name' route_param %}">click here</a> <a href="{% url 'exampleapp:http_example' %}">click here</a> <a href="{% url 'exampleapp:http_example_with_param' id %}">click here</a> <a href="{% url 'exampleapp:json_example' %}">click here</a> <a href="{% url 'exampleapp:html_example' %}">click here</a>
Template inheritance¶
inheritance of template is used to avaoid code duplication, and clean your code first of all you must set the layout (a htmlpage with blocks) that you will extend
<!DOCTYPE html> <html lang="en"> <head> <title>{% block title %}{% endblock %}</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> {% load static %} <link rel="stylesheet" href="{% static "css/bootstrap.min.css" %}"> <link rel="stylesheet" href="{% static "css/yeti.min.css" %}"> {% block stylesheets %}{% endblock %} </head> <body> {% block content %}{% endblock %} <script src="{% static "js/jquery.min.js" %}"></script> <script src="{% static "js/popper.min.js" %}"></script> <script src="{% static "js/bootstrap.min.js" %}"></script> {% block javascript %}{% endblock %} </body> </html>
and then create a page that extend the layout
{% extends 'layout.html' %} {% block title %}Example app{% endblock %} {% block content %} <div class="container mt-5"> <h1>Hello World</h1> </div> {% endblock %}
Django data¶
django come with a strong ORM (object-relational-mapping) in this section we will use it.
models¶
this link contain all the possible fields of any model (https://docs.djangoproject.com/en/3.0/topics/db/models/)
#example of a model from django.db import models class Event(models.Model): name = models.CharField(max_length=120, null=False, blank=False) event_date = models.DateTimeField(null=False, blank=False) venue = models.CharField(max_length=120, null=False, blank=False) description = models.TextField(null=False, blank=False)
models relations¶
This link contain all the possible models relations (https://hackernoon.com/django-orm-relationships-cheat-sheet-14433d6cf68c)
migrations¶
In Terminal
python manage.py makemigrations
python manage.py migrate
ORM methods¶
in general the orm methods will be used in our views to get data from the DB and pass it to the templates
#get many Model.objects.all() Model.objects.filter(Field=Value) #get One Model.objects.get(id=1) Model.objects.get(pk=1) Model.objects.get(field=Value) #save a record d = Model(field=Value, Field=Value) #here you must set the mandatory fields d.save() #update a record d.field = Value d.save() #delete a record d2 = Model.objects.get(pk=1) d2.delete() #count Model.objects.all().count()
users and admin site¶
django came with a predefined Back-office which is the admin site. in the admin site we must add our models that need to be managed
# in the admin.py of our application from .models import Event #import your model admin.site.register(Event) # register your model
In Terminal
python manage.py createsuperuser
Django form¶
handling from is very easy in django, simply you must create a form in the template and then recieve the fields in a view
<form action="{% url 'app_name:route_name' %}" method="post"> {% csrf_token %} <input type="text" name="x" value="" placeholder="add an x"> <input type="submit" value="Add"> </form>
#import reverse from django.urls #import HttpResponseRedirect from django.http def add(request): x = request.POST.get('x') return HttpResponseRedirect(reverse('app_name:route_name', args=(x,))) #args is mandatory if the route have paramaters
Django users and authentication¶
here are some useful links for the users and authentication system
- Login_tutorial : https://wsvincent.com/django-user-authentication-tutorial-login-and-logout/
- Login tutorial 2 : https://python.doctor/page-django-login-authentification-de-base-apprendre-creer-cours-tutoriel-python
- Login tutorial 3 : https://simpleisbetterthancomplex.com/tutorial/2016/06/27/how-to-use-djangos-built-in-login-system.html
-
Login tutorial 4 : https://pythonprogramming.net/user-login-logout-django-tutorial/
-
Auth system : https://wsvincent.com/django-allauth-tutorial-custom-user-model/
-
Modify the user model : https://wsvincent.com/django-custom-user-model-tutorial/
-
Modify the user model 2 : https://simpleisbetterthancomplex.com/tutorial/2018/01/18/how-to-implement-multiple-user-types-with-django.html
-
customize the form object : https://stackoverflow.com/questions/7769805/editing-django-form-as-p
- customize the form object 2 : https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html
authentication Example¶
here a sample of code: our authentication system based on the user model of django
if the user is_staff so he will be redirected to admin_portal,
if the user is_not_staff he will be redirected to the club_portal
first of all we need our routes
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), # route for the authentication page path('club/', views.club, name='club_portal'), # route for the club space path('admin/', views.admin, name='admin_portal'), # route for the admin space path('login/', views.login_view, name='login'), # route for login path('logout/', views.logout_view, name='logout'), # route for logout ]
then we must code our views
from django.contrib.auth import authenticate, login, logout from django.http import HttpResponseRedirect from django.shortcuts import render from django.urls import reverse def index(request): if request.user.is_authenticated: # we test if the user already authenticated if request.user.is_staff: # make redirection based on is_staff or not return HttpResponseRedirect(reverse('admin_portal', args=())) elif not request.user.is_staff: return HttpResponseRedirect(reverse('club_portal', args=())) else: # if the user not authenticated, we must show him the login page return render(request, 'login.html') def login_view(request): # get the form params username = request.POST.get('username', False) password = request.POST.get('password', False) user = authenticate(username=username, password=password) #autheticate if user is not None and user.is_active: # if the authetication goes well and the user is active login(request, user) # do the login in django sytem # make redirection based on user is_staff or not # if is_staff --> admin page # if not is_staff --> club page # otherwise --> login page if user.is_staff: return HttpResponseRedirect(reverse('admin_portal', args=())) elif not user.is_staff: return HttpResponseRedirect(reverse('club_portal', args=())) else: return render(request, 'login.html') def logout_view(request): logout(request) return render(request, 'login.html') def club(request): return render(request, 'club.html') def admin(request): return render(request, 'admin.html')
and finally our html pages
<!--login page--> <form method="post" role="form" action="{% url 'login' %}"> {% csrf_token %} <input type="text" name="username" placeholder="Utilisateur"> <input type="password" name="password" placeholder="Mot de passe"> <input type="submit" value="login" /> </form> <!--club portal--> {% if user.is_authenticated and not user.is_staff %} Hi {{ user.username }}!, you are a club <br> <a href="{% url 'logout' %}">logout</a> {% else %} <p>You are not logged in</p> <a href="{% url 'index' %}">login from here</a> {% endif %} <!--admin portal--> {% if user.is_authenticated and user.is_staff %} Hi {{ user.username }}!, you are administrator <br> <a href="{% url 'logout' %}">logout</a> {% else %} <p>You are not logged in</p> <a href="{% url 'index' %}">login from here</a> {% endif %}