Practice the Django tutorial that is on the MDN website on Windows. link to the tutorial
Learn Django from scratch. Including setting up dev environment, defining models, Django admin site, auth and permissions, testing, security, etc. Build a local library website and deploy it on Heroku.
- My notes
- Django introduction
- Setting up a Django development environment
- Django Tutorial: The Local Library website
- Django Tutorial Part2: Creating a skeleton website
- Django Tutorial Part3: Using models
- Django Tutorial Part4: Django admin site
- Django Tutorial Part5: Creating our home page
- Django Tutorial Part6: Generic list and detail views
- Django Tutorial Part7: Sessions framework
- Django Tutorial Part8: User authentication and permissions
- Django Tutorial Part9: Working with forms
- Django Tutorial Part10: Testing a Django web application
- Django Turorial Part11: Deploying Django to production
- Django web application security
- install Python, pip
- setup virtual environment
- install Django
-
Creating the project
-
open a terminal, in the virtual environment (command: workon)
-
create a folder
-
create the new project
django-admin startproject locallibrary cd locallibrary
-
-
Creating the catalog application
py manage.py startapp catalog
-
Registering the catalog application
-
settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Add our new application 'catalog.apps.CatalogConfig', #This object was created for us in /catalog/apps.py ]
-
-
Specifying the database
-
settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
-
-
Hooking up the URL mapper
-
locallibrary/urls.py
from django.contrib import admin from django.urls import path from django.urls import include from django.views.generic import RedirectView from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('catalog/', include('catalog.urls')), # Use include() to add paths from the catalog application path('', RedirectView.as_view(url='catalog/', permanent=True)), # Add URL maps to redirect the base URL to our application ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) # Use static() to add url mapping to serve static files during development (only)
-
catalog/urls.py
from django.urls import path from . import views urlpatterns = [ ]
-
-
Run
py manage.py makemigrations py manage.py migrate py manage.py runserver
lookups files and docs.
record = MyModelName(my_field_name="Instance #1") # Create using ctr.
record.save() # Save into database.
all_books = Book.objects.all() # get all records
wild_books = Book.objects.filter(title__contains='wild')
number_wild_books = wild_books.count()
-
Registering models:
catalog/admin.py
from .models import Author admin.site.register(Author)
-
Creating a superuser
py manage.py createsuperuser
-
Register a ModelAdmin class:
catalog/admin.py
@admin.register(Author) class AuthorAdmin(admin.ModelAdmin): list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death') # list table cols fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')] # detail view inlines = [BooksInline] # inline editing of associated records @admin.register(BookInstance) class BookInstanceAdmin(admin.ModelAdmin): list_filter = ('status', 'due_back') # filter box to the right # sectioning the detail view fieldsets = ( (None, { 'fields': ('book', 'imprint', 'id') }), ('Availability', { 'fields': ('status', 'due_back') }), )
-
Referencing static files in templates
{% load static %} <link rel="stylesheet" href="{% static 'css/styles.css' %}" /> <img src="{% static 'catalog/images/local_library_model_uml.png' %}" />
-
Configuring where to find the templates:
settings.py
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], # specify locations to search 'APP_DIRS': True, 'OPTIONS': { # ... ], }, }, ]
-
Specify template, pass additional context variables.
views.py
class BookListView(generic.ListView): # ... template_name = 'books/my_arbitrary_template_name_list.html' # Specify your own template name/location # pass additional context variables def get_context_data(self, **kwargs): context = super(BookListView, self).get_context_data(**kwargs) context['some_data'] = 'This is just some data' return context
-
Passing additional options in your URL maps
# use the same view for multiple templates path('url/', views.my_reused_view, {'my_template_name': 'some_path'}, name='aurl'), path('anotherurl/', views.my_reused_view, {'my_template_name': 'another_path'}, name='anotherurl'),
-
Enabling sessions: enabled automatically.
settings.py
INSTALLED_APPS = [ ... 'django.contrib.sessions', .... MIDDLEWARE = [ ... 'django.contrib.sessions.middleware.SessionMiddleware', ....
-
Saving session data
# Session object not directly modified, only data within the session. Session changes not saved! request.session['my_car']['wheels'] = 'alloy' # Set session as modified to force data updates/cookie to be saved. request.session.modified = True # or add project setting below # SESSION_SAVE_EVERY_REQUEST = True
-
Enabling authentication: enabled automatically.
settings.py
INSTALLED_APPS = [ ... 'django.contrib.auth', # Core authentication framework and its default models. 'django.contrib.contenttypes', # Django content type system (allows permissions to be associated with models). ... MIDDLEWARE = [ ... 'django.contrib.sessions.middleware.SessionMiddleware', # Manages sessions across requests ... 'django.contrib.auth.middleware.AuthenticationMiddleware', # Associates users with requests using sessions. ...
-
Project URLs:
locallibrary/urls.py
urlpatterns += [ path('accounts/', include('django.contrib.auth.urls')), ] # automatically maps the below URLs. # accounts/ login/ [name='login'] # accounts/ logout/ [name='logout'] # accounts/ password_change/ [name='password_change'] # accounts/ password_change/done/ [name='password_change_done'] # accounts/ password_reset/ [name='password_reset'] # accounts/ password_reset/done/ [name='password_reset_done'] # accounts/ reset/<uidb64>/<token>/ [name='password_reset_confirm'] # accounts/ reset/done/ [name='password_reset_complete']
-
Redirect:
settings.py
# Redirect to home URL after login (Default redirects to /accounts/profile/) LOGIN_REDIRECT_URL = '/'
-
Login required
from django.contrib.auth.decorators import login_required # If the user is not logged in, redirect to the login URL defined in the settings.LOGIN_URL @login_required def my_view(request): ...
from django.contrib.auth.mixins import LoginRequiredMixin class MyView(LoginRequiredMixin, View): login_url = '/#/' # optional redirect_field_name = 'redirect_to' # optional
-
Permissions
-
Models
class BookInstance(models.Model): ... class Meta: ... # tuple containing the name and display value permissions = (("can_mark_returned", "Set book as returned"),)
-
Templates
{% if perms.catalog.can_mark_returned %} <!-- We can mark a BookInstance as returned. --> <!-- Perhaps add code to link to a "book return" view here. --> {% endif %} {% if user.is_staff %} <!-- content is for staff only --> {% endif %}
-
Views
from django.contrib.auth.decorators import permission_required # logged-in user with a permission violation: redirects to login(Status 302) @permission_required('catalog.can_mark_returned') @permission_required('catalog.can_edit') def my_view(request): ...
from django.contrib.auth.decorators import login_required, permission_required @login_required @permission_required('catalog.can_mark_returned', raise_exception=True) def my_view(request): ...
from django.contrib.auth.mixins import PermissionRequiredMixin class MyView(PermissionRequiredMixin, View): permission_required = 'catalog.can_mark_returned' # Or multiple permissions permission_required = ('catalog.can_mark_returned', 'catalog.can_edit') # Note that 'catalog.can_edit' is just an example.The catalog application doesn't have such permission!
-
lookups files and docs.
class YourTestClass(TestCase):
def setUp(self):
# Setup run before every test method.
pass
def tearDown(self):
# Clean up run after every test method.
pass
def test_something_that_will_pass(self):
self.assertFalse(False)
def test_something_that_will_fail(self):
self.assertTrue(False)
<!-- Django will discover tests under the current working directory in any file named with the pattern test*.py -->
catalog/ /tests/ __init__.py test_models.py test_forms.py test_views.py
python3 manage.py collectstatic
python3 manage.py test
python3 manage.py test catalog.tests.test_models.YourTestClass.test_one_plus_one_equals_two
settings.py
DEBUG = False
# Read SECRET_KEY from an environment variable
import os
SECRET_KEY = os.environ['SECRET_KEY']
# OR
# Read secret key from a file
with open('/etc/secret_key.txt') as f:
SECRET_KEY = f.read().strip()
- ALLOWED_HOSTS
- DATABASES
- STATIC_ROOT and STATIC_URL
- ...
- Cross site scription (XSS)
- Cross site request forgery (CSRF)
- SQL injection
- Clickjacking
- SSL/HTTPS