Skip to content

Latest commit

 

History

History
376 lines (265 loc) · 7.08 KB

Django.md

File metadata and controls

376 lines (265 loc) · 7.08 KB

URLs/Views

  • Requesting a page

Browser -> urls.py -> views.py

  • The browser fires off a request to urls.py and decides which function to fire in views.py
  • This function controls what happens when the user visits the requested URL
  • views.py sends the HTML template/response to the browser
# urls.py
# . from same directory
from . import views
from django.urls import re_path

# use regex to pattern match urls
urlpatterns = [
  # calls views.homepage as a callback 
    re_path(r'^$', views.home),
]
# views.py
from django.http import HttpResponse

def home(request):
    return HttpResponse('<h1>home</h1>')
  • HttpResponse is HTML

HTML Templates

  • Return render of a template
# views.py
from django.shortcuts import render

def home(request):
    return render(request, 'home.html')

Apps

  • Separate websites into apps for each section of a website

python manage.py startapp articles

# settings.py

INSTALLED_APPS = [
  ...
  'appname'
]
# main/urls.py
urlpatterns = [
  path(..., include('app.urls'))
]
  • Include new app urls
  • Whenever someone goes to /app it will first look at the urls in the app/urls.py

Models

  • Classes which represent a table in a database
  • Each type of data is represented in a model
  • Each model maps to a single table in a database
  • The database stores instances of each model
  • Specify data type of Model fields
# models.py
class Article(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField()
    body = models.TextField()
    date = models.DateTimeField(auto_now_add=True)

Migrations

python manage.py makemigrations

  • Create a migration file
  • Tracks changes to a model
  • When we run python manage.py migrate, the migration file will mirror the model to the specified database table
  • Every time we make/change a model we must make migrations and migrate them

python manage.py migrate

  • Migrate models to the database

Django ORM

from dir.models import Cool

  • Import Cool model from models.py from the dir directory

Cool.objects.all()

  • Retrieve all rows (models/objects) from the table

me = Cool()

  • Create new Cool model instance

me.save()

  • Save model instance to database

Cool.objects.all()

  • Get all objects in the Cool table
  • Cool.objects.all()[0].title gets the title property of the first index

Formatting model retrieval

def __str__(self):
    return self.title
  • Now calling models ex. Cool.objects.all() will return the model title

Django Admin

python manage.py createsuperuser

  • Create admin account
  • No email necessary

Model Registration

  • Allows for GUI viewing/editing for models
# admin.py
from .models import Article 

admin.site.register(Article)
  • Import Article model from models.py in the current directory
  • Register Article model on admin site (GUI interface)

Template Tags

  • Insert Python logic data into HTML

{% %} - no output

{{ }} - output data

# views.py
def article_list(request):
    articles = Article.objects.all().order_by('date')
    return render(request, 'articles/article_list.html', {'articles': articles})
  • The third parameter (dictionary) passes in articles as prop
article_list.html

{% for article in articles %}
    <h1>{{ article.title }}</h1>
    <p>{{ article.body }}</p>
{% endfor %}

Static Files

  • CSS, JS
  • Files we serve up to the client browser
# urls.py
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
  ...
]

# append static file stuff
urlpatterns += staticfiles_urlpatterns()
  • Look inside settings.py to find the static URL
# settings.py
STATIC_URL = '/static/'

STATICFILES_DIRS = (
  # look in base directory and then in the assets folder
    os.path.join(BASE_DIR, 'assets'),
)
  • ex. styles.css: url/static/styles.css

Static Module

{% load static %}
<link rel="stylesheet" href="{% static 'styles.css' %}"
  • Load in static file styles.css dynamically

Extending Templates

  • Create a base global template with other templates extending the base
base.html
...
<body>
    {% block content %}
    {% endblock %}
</body>
extend.html

{% extends 'base.html' %}
{% block content %}
    <p>HTML that is to be injected into the base template</p>
{% endblock %}

URL Parameters

  • Use slugs in URLs
# urls.py
urlpatterns = [
  ...,
    path('<slug:slug>', views.article_detail)
]
  • <slug is the type of the passed parameter
  • :slug> is the name of the parameter
def article_detail(request, slug):
  • request is views.article_detail
  • slug is the path we passed in

Named URL's

  • Hooking up links to their respective slug
path('<slug:slug>', views.article_detail, name="detail")
base.html
<a href="{% url 'detail' %}"</a>

Namespacing URLs

# articles/urls.py
app_name = 'articles'
base.html
<a href="{% url 'articles:detail' %}"</a>

Uploading Media

# settings.py

# url/media/image.png
MEDIA_URL = '/media/'

# host files in media folder
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# urls.py

# Tells Django where the media files are
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
  ...
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Adding in an image field

# articles.py
class Article(models.Model):
    ...
    thumb = models.ImageField(default='default.png', blank=True)
  • default: default image
  • blank=True: optional field

After making model changes, remember to migrate!

User Accounts

  • Django comes pre-built with forms
# accounts/views.py

from django.contrib.auth.forms import UserCreationForm

def signup_view(request):
    form = UserCreationForm()
    return render(request, 'accounts/signup.html', {'form': form})
# accounts/signup.html
<form class="site-form" action="/accounts/signup/" method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit">
    </form>
  • Need csrf_token to verify POST is coming from us, not 3rd party

Saving Users

  • signup_view(request) is called on GET and POST requests
  • Depending on the request type, we can perform different tasks
def signup_view(request):
    if request.method = 'POST':
        form = UserCreationForm(request.POST) # this line takes POST data and validates it
        if form.is_valid(): # if form valid, save to db
            form.save()
            # log user in
            return redirect('articles:list')
    else: # GET requests
        form = UserCreationForm()
        
    return render(request, 'accounts/signup.html', {'form': form})
  • 1: POST request, user is created if form valid
  • 2: GET request, send signup page to user
  • 3: POST request, form invalid and signup page is re-rendered with errors