Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DjangoCon US 2022 - Solving the Django Jigsaw P...

DjangoCon US 2022 - Solving the Django Jigsaw Puzzle

Learning Django often feels like trying to solve an immense jigsaw puzzle with the pieces all turned upside down. It’s hard to align all the pieces when you don’t know how they should fit together.

This talk is based on over a decade of using and teaching Django professionally. I will cover all the major puzzle pieces of Django: how they work independently and together. I don’t expect anyone to have mastery over all these pieces–I certainly don’t–but knowing the overall picture of Django and what the pieces are will provide a roadmap for learning and improving your Django abilities no matter your current level.

William S. Vincent

November 01, 2022
Tweet

More Decks by William S. Vincent

Other Decks in Technology

Transcript

  1. DjangoCon US 2022 | William Vincent The Django Jigsaw Puzzle

    Will Vincent DjangoCon US 2022 Aligning All the Pieces
  2. DjangoCon US 2022 | William Vincent Who am I? •

    DSF Board (Treasurer) • LearnDjango.com • Django Chat podcast • Django News newsletter • awesome-django, DjangoX ...
  3. DjangoCon US 2022 | William Vincent startproject <project_name>/ ├── <project_name>

    │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py (.venv) $ django-admin startproject <project_name>
  4. DjangoCon US 2022 | William Vincent startproject . ├── django_project

    │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py (.venv) $ django-admin startproject <project_name>
  5. DjangoCon US 2022 | William Vincent wsgi.py & asgi.py #

    django_project/settings.py ├── django_project │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py
  6. DjangoCon US 2022 | William Vincent Django Commands # creates

    new project boilerplate (.venv) $ django-admin startproject <project_name> # Creates app folder and files (.venv) $ python manage.py startapp <app_name> # Create migrations file and prepares database for update (.venv) $ python manage.py makemigrations # Runs the migrations and updates database (.venv) $ python manage.py migrate # Create superuser with admin-level permissions (.venv) $ python manage.py createsuperuser
  7. DjangoCon US 2022 | William Vincent db.sqlite3 # django_project/settings.py ├──

    djago_project │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── db.sqlite3
  8. DjangoCon US 2022 | William Vincent Apps (.venv) $ python

    manage.py startapp blog ├── django_project │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── db.sqlite3 ├── blog │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py
  9. DjangoCon US 2022 | William Vincent INSTALLED_APPS # django_project/settings.py INSTALLED_APPS

    = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "blog", # new ]
  10. DjangoCon US 2022 | William Vincent Models # blog/models.py from

    django.db import models from django.urls import reverse class Post(models.Model): title = models.CharField(max_length=200) body = models.TextField() def __str__(self): return self.title def get_absolute_url(self): return reverse("post_detail", kwargs={"pk": self.pk})
  11. DjangoCon US 2022 | William Vincent Admin # blog/admin.py from

    django.contrib import admin from .models import Post admin.site.register(Post)
  12. DjangoCon US 2022 | William Vincent Views # blog/views.py from

    django.views.generic import ListView, DetailView from .models import Post class BlogListView(ListView): model = Post template_name = "home.html" class BlogDetailView(DetailView): model = Post template_name = "post_detail.html"
  13. DjangoCon US 2022 | William Vincent URL Routing # django_project/urls.py

    from django.contrib import admin from django.urls import path, include urlpatterns = [ path("admin/", admin.site.urls), path("", include("blog.urls")), ] # blog/urls.py from django.urls import path from .views import BlogListView, BlogDetailView urlpatterns = [ path("post/<int:pk>/", BlogDetailView.as_view(), name="post_detail"), path("", BlogListView.as_view(), name="home"), ]
  14. DjangoCon US 2022 | William Vincent Templates # blog/templates/blog/template_file.html <!--

    Variables --> {{ variable }} <! -- Tags --> {% tag %} <ul> {% for book in book_list %} <li>{{ book.title }}</li> {% endfor %} </ul>
  15. DjangoCon US 2022 | William Vincent Templates Directory # django_project/settings.py

    TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [BASE_DIR / "templates"], # new ...
  16. DjangoCon US 2022 | William Vincent base.html # templates/base.html <html>

    <head> <title>Django blog</title> </head> <body> <header> <h1><a href="{% url 'home' %}">Django blog</a></h1> </header> <div> {% block content %} {% endblock content %} </div> </body> </html>
  17. DjangoCon US 2022 | William Vincent home.html # templates/home.html {%

    extends "base.html" %} {% block content %} {% for post in post_list %} <div class="post-entry"> <h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></h2> <p>{{ post.body }}</p> </div> {% endfor %} {% endblock content %}
  18. DjangoCon US 2022 | William Vincent post_detail.html # templates/post_detail.html {%

    extends "base.html" %} {% block content %} <div class="post-entry"> <h2>{{ post.title }}</h2> <p>{{ post.body }}</p> </div> {% endblock content %}
  19. DjangoCon US 2022 | William Vincent Static Files ├── blog

    │ ├── ... ├── db.sqlite3 ├── django_project │ ├── ... ├── manage.py └── static └── css └── base.css
  20. DjangoCon US 2022 | William Vincent Static Files/Templates /* templates/css/base.css

    */ h1 { color: red; } <!-- templates/base.html --> {% load static %} <html> <head> <title>Django blog</title> <link rel="stylesheet" href="{% static 'css/base.css' %}"> # django_project/settings.py STATIC_URL = "static/" # already set STATICFILES_DIRS = [BASE_DIR / "static"]
  21. DjangoCon US 2022 | William Vincent Middleware Middleware 1 --|

    v Middleware 2 --| v Middleware 3 --| v |-- View v Middleware 3 v Middleware 2 v Middleware 1
  22. DjangoCon US 2022 | William Vincent Middleware # django_project/settings.py 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", ]
  23. DjangoCon US 2022 | William Vincent Authentication # django_project/settings.py INSTALLED_APPS

    = [ "django.contrib.admin", "django.contrib.auth", # Hi!!!!!! ... "blog", ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", ... "django.contrib.auth.middleware.AuthenticationMiddleware", # Hi!!!!!! ]
  24. DjangoCon US 2022 | William Vincent Password Reset # django_project/settings.py

    EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" EMAIL_HOST = "smtp.gmail.com" EMAIL_PORT = 587 EMAIL_USE_TLS = True EMAIL_HOST_USER = "YOUR_EMAIL" EMAIL_HOST_PASSWORD = "YOUR_EMAIL_PASSWORD"
  25. DjangoCon US 2022 | William Vincent CSRF (Cross-Site-Request Forgery) #

    django_project/settings.py 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", ]
  26. DjangoCon US 2022 | William Vincent CSRF (Cross-Site-Request Forgery) <!--

    templates/post_new.html --> {% extends "base.html" %} {% block content %} <h1>New post</h1> <form action="" method="post">{% csrf_token %} {{ form.as_p }} <input type="submit" value="Save"> </form> {% endblock content %}
  27. DjangoCon US 2022 | William Vincent Django Shell $ python

    manage.py shell >>> from blog.models import Blog >>> Blog.objects.all()
  28. DjangoCon US 2022 | William Vincent Testing # blog/tests.py from

    django.test import TestCase from myapp.models import Animal class AnimalTestCase(TestCase): def setUp(self): Animal.objects.create(name="lion", sound="roar") Animal.objects.create(name="cat", sound="meow") def test_animals_can_speak(self): """Animals that can speak are correctly identified""" lion = Animal.objects.get(name="lion") cat = Animal.objects.get(name="cat") self.assertEqual(lion.speak(), 'The lion says "roar"') self.assertEqual(cat.speak(), 'The cat says "meow"')
  29. DjangoCon US 2022 | William Vincent Other Goodies • Messages

    • Signals • Internationalization / Localization • GeoDjango • Async
  30. DjangoCon US 2022 | William Vincent Environment Variables # django_project/settings.py

    from pathlib import Path from environs import Env # new env = Env() # new env.read_env() # new SECRET_KEY = env.str("SECRET_KEY") DEBUG = env.bool("DEBUG", default=False) ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=[]) CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=[])
  31. DjangoCon US 2022 | William Vincent Production Database # django_project/settings.py

    DATABASES = { "default": env.dj_db_url("DATABASE_URL", default="postgres://postgres@db/postgres") }
  32. DjangoCon US 2022 | William Vincent Production Static Files •

    Install `whitenoise` • Update `INSTALLED_APPS` and `MIDDLEWARE` # django_project/settings.py STATIC_URL = "/static/" STATICFILES_DIRS = [BASE_DIR / "static"] STATIC_ROOT = BASE_DIR / "staticfiles" STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
  33. DjangoCon US 2022 | William Vincent Media Files # django_project/settings.py

    MEDIA_URL = "/media/" MEDIA_ROOT = BASE_DIR / "media" ├── blog │ ├── ... ├── db.sqlite3 ├── django_project │ ├── ... ├── manage.py ├── media | └── images └── static └── css └── base.css
  34. DjangoCon US 2022 | William Vincent Django Software Foundation Anna

    Makarudze (President) Chaim Kirby (Vice President) Mfon Eti-mfon (Secretary) William Vincent (Treasurer) Kátia Nakamura Aaron Bassett Žan Anderle