You are on page 1of 4

Beginner's Python

Working with models Building a simple home page


The data in a Django project is structured as a set of Users interact with a project through web pages, and a
models. project’s home page can start out as a simple page with no

Cheat Sheet – Django Defining a model


To define the models for your app, modify the file models.py that
was created in your app’s folder. The __str__() method tells
data. A page usually needs a URL, a view, and a template.
Mapping a project’s URLs
The project’s main urls.py file tells Django where to find the urls.py
Django how to represent data objects based on this model. files associated with each app in the project.
What is Django? from django.db import models from django.contrib import admin
from django.urls import path, include
Django is a web framework which helps you build class Topic(models.Model):
interactive websites using Python. With Django you """A topic the user is learning about.""" urlpatterns = [
define the kind of data your site needs to work with, path('admin/', admin.site.urls),
and you define the ways your users can work with text = models.CharField(max_length=200) path('', include('learning_logs.urls')),
that data. date_added = models.DateTimeField( ]
auto_now_add=True)
Mapping an app’s URLs
Installing Django An app’s urls.py file tells Django which view to use for each URL in
def __str__(self):
It’s usually best to install Django to a virtual environment, the app. You’ll need to make this file yourself, and save it in the
return self.text
where your project can be isolated from your other Python app’s folder.
projects. Most commands assume you’re working in an Activating a model from django.urls import path
active virtual environment. To use a model the app must be added to the list
INSTALLED_APPS, which is stored in the project’s settings.py file.
Create a virtual environment from . import views
INSTALLED_APPS = [
$ python –m venv ll_env # My apps. app_name = 'learning_logs'
Activate the environment (macOS and Linux) 'learning_logs', urlpatterns = [
# Home page.
$ source ll_env/bin/activate # Default Django apps. path('', views.index, name='index'),
'django.contrib.admin', ]
Activate the environment (Windows)
]
> ll_env\Scripts\activate Writing a simple view
Migrating the database A view takes information from a request and sends data to the
Install Django to the active environment The database needs to be modified to store the kind of data that browser, often through a template. View functions are stored in an
the model represents. You'll need to run these commands every app’s views.py file. This simple view function doesn’t pull in any
(ll_env)$ pip install Django time you create a new model, or modify an existing model. data, but it uses the template index.html to render the home page.

$ python manage.py makemigrations learning_logs from django.shortcuts import render


Creating a project $ python manage.py migrate
To start a project we’ll create a new project, create a def index(request):
Creating a superuser """The home page for Learning Log."""
database, and start a development server. A superuser is a user account that has access to all aspects of the return render(request,
Create a new project project. 'learning_logs/index.html')
$ django-admin startproject learning_log . $ python manage.py createsuperuser
Registering a model Online resources
Create a database
You can register your models with Django’s admin site, which The documentation for Django is available at
$ python manage.py migrate makes it easier to work with the data in your project. To do this, http://docs.djangoproject.com/. The Django documentation
modify the app’s admin.py file. View the admin site at is thorough and user-friendly, so check it out!
View the project http://localhost:8000/admin/.
After issuing this command, you can view the project at
http://localhost:8000/. from django.contrib import admin
Python Crash Course
$ python manage.py runserver from .models import Topic A Hands-On, Project-Based
Create a new app Introduction to Programming
A Django project is made up of one or more apps.
admin.site.register(Topic)

$ python manage.py startapp learning_logs nostarch.com/pythoncrashcourse2e


Building a simple home page (cont.) Another model Building a page with data (cont.)
A new model can use an existing model. The ForeignKey
Writing a simple template attribute establishes a connection between instances of the Using data in a template
A template sets up the structure for a page. It’s a mix of html and The data in the view function’s context dictionary is available
template code, which is like Python but not as powerful. Make a
two related models. Make sure to migrate the database
within the template. This data is accessed using template
folder called templates inside the project folder. Inside the after adding a new model to your app. variables, which are indicated by doubled curly braces.
templates folder make another folder with the same name as the The vertical line after a template variable indicates a filter. In this
app. This is where the template files should be saved.
Defining a model with a foreign key
case a filter called date formats date objects, and the filter
The home page template will be saved as class Entry(models.Model): linebreaks renders paragraphs properly on a web page.
learning_logs/templates/learning_logs/index.html. """Learning log entries for a topic.""" {% extends 'learning_logs/base.html' %}
<p>Learning Log</p> topic = models.ForeignKey(Topic,
on_delete=models.CASCADE) {% block content %}
<p>Learning Log helps you keep track of your text = models.TextField()
learning, for any topic you're learning date_added = models.DateTimeField( <p>Topic: {{ topic }}</p>
about.</p> auto_now_add=True)
<p>Entries:</p>
def __str__(self):
Template inheritance return f"{self.text[:50]}..."
<ul>
Many elements of a web page are repeated on every page {% for entry in entries %}
in the site, or every page in a section of the site. By writing <li>
one parent template for the site, and one for each section, Building a page with data <p>
you can easily modify the look and feel of your entire site. Most pages in a project need to present data that’s specific {{ entry.date_added|date:'M d, Y H:i' }}
to the current user. </p>
The parent template <p>
The parent template defines the elements common to a set of URL parameters {{ entry.text|linebreaks }}
pages, and defines blocks that will be filled by individual pages. A URL often needs to accept a parameter telling it which data to </p>
access from the database. The URL pattern shown here looks for
<p> the ID of a specific topic and assigns it to the parameter topic_id.
</li>
<a href="{% url 'learning_logs:index' %}"> {% empty %}
Learning Log urlpatterns = [ <li>There are no entries yet.</li>
</a> --snip-- {% endfor %}
</p> # Detail page for a single topic. </ul>
path('topics/<int:topic_id>/', views.topic,
{% block content %}{% endblock content %} name='topic'), {% endblock content %}
]
The child template
The child template uses the {% extends %} template tag to pull in Using data in a view
the structure of the parent template. It then defines the content for The view uses a parameter from the URL to pull the correct data The Django shell
any blocks defined in the parent template. from the database. In this example the view is sending a context You can explore the data in your project from the command
dictionary to the template, containing data that should be displayed line. This is helpful for developing queries and testing code
{% extends 'learning_logs/base.html' %} on the page. You'll need to import any model you're using. snippets.
{% block content %} def topic(request, topic_id): Start a shell session
"""Show a topic and all its entries."""
topic = Topic.objects.get(id=topic_id) $ python manage.py shell
<p>
entries = topic.entry_set.order_by(
Learning Log helps you keep track
'-date_added')
Access data from the project
of your learning, for any topic you're
learning about. context = { >>> from learning_logs.models import Topic
</p> 'topic': topic, >>> Topic.objects.all()
'entries': entries, [<Topic: Chess>, <Topic: Rock Climbing>]
{% endblock content %} } >>> topic = Topic.objects.get(id=1)
return render(request, >>> topic.text
'learning_logs/topic.html', context) 'Chess'
Template indentation
Python code is usually indented by four spaces. In Restarting the development server
templates you’ll often see two spaces used for indentation, If you make a change to your project and the change
because elements tend to be nested more deeply in More cheat sheets available at
doesn’t seem to have any effect, try restarting the server:
templates. $ python manage.py runserver ehmatthes.github.io/pcc_2e/
Beginner's Python
User accounts (cont.) User accounts (cont.)
Defining the URLs Showing the current login status

Cheat Sheet –
Users will need to be able to log in, log out, and register. Make a You can modify the base.html template to show whether the user is
new urls.py file in the users app folder. currently logged in, and to provide a link to the login and logout
pages. Django makes a user object available to every template,
from django.urls import path, include and this template takes advantage of this object.

Django, Part 2 from . import views


The user.is_authenticated tag allows you to serve specific
content to users depending on whether they have logged in or not.
The {{ user.username }} property allows you to greet users
app_name = 'users' who have logged in. Users who haven’t logged in see links to
urlpatterns = [ register or log in.

Users and forms # Include default auth urls. <p>


path('', include( <a href="{% url 'learning_logs:index' %}">
Most web applications need to let users create 'django.contrib.auth.urls')), Learning Log
accounts. This lets users create and work with their </a>
own data. Some of this data may be private, and # Registration page.
some may be public. Django’s forms allow users to path('register/', views.register, {% if user.is_authenticated %}
enter and modify their data. name='register'), Hello, {{ user.username }}.
] <a href="{% url 'users:logout' %}">
User accounts Log out
The login template
The login view is provided by default, but you need to provide your
</a>
User accounts are handled by a dedicated app called {% else %}
users. Users need to be able to register, log in, and log own login template. The template shown here displays a simple
login form, and provides basic error messages. Make a templates <a href="{% url 'users:register' %}">
out. Django automates much of this work for you. folder in the users folder, and then make a registration folder in the Register
Making a users app templates folder. Save this file as login.html. </a> -
The tag {% csrf_token %} helps prevent a common type of <a href="{% url 'users:login' %}">
After making the app, be sure to add 'users' to INSTALLED_APPS
attack with forms. The {{ form.as_p }} element displays the Log in
in the project’s settings.py file.
default login form in paragraph format. The <input> element
</a>
$ python manage.py startapp users named next redirects the user to the home page after a successful
login.
{% endif %}
Including URLS for the users app
Add a line to the project’s urls.py file so the users app’s URLs are {% extends "learning_logs/base.html" %} </p>
included in the project.
{% block content %} {% block content %}{% endblock content %}
from django.contrib import admin {% if form.errors %}
from django.urls import path, include <p> The logged_out template
Your username and password didn't match. The default logout view renders the page using the template
urlpatterns = [ logged_out.html, which needs to be saved in the
Please try again.
path('admin/', admin.site.urls), users/templates/registration folder.
</p>
path('users/', include('users.urls')), {% endif %} {% extends "learning_logs/base.html" %}
path('', include('learning_logs.urls')),
] <form method="post" {% block content %}
action="{% url 'users:login' %}"> <p>
You have been logged out. Thank you
Using forms in Django {% csrf token %} for visiting!
There are a number of ways to create forms and work with {{ form.as_p }} </p>
them. You can use Django’s defaults, or completely <button name="submit">Log in</button> {% endblock content %}
customize your forms. For a simple way to let users enter
data based on your models, use a ModelForm. This creates
Python Crash Course
<input type="hidden" name="next"
a form that allows users to enter data that will populate the value="{% url 'learning_logs:index' %}"/>
fields on a model.
The register view on the back of this sheet shows a simple A Hands-On, Project-Based
</form>
approach to form processing. If the view doesn’t receive Introduction to Programming
data from a form, it responds with a blank form. If it {% endblock content %}
receives POST data from a form, it validates the data and nostarch.com/pythoncrashcourse2e
then saves it to the database.
User accounts (cont.) User accounts (cont.) Connecting data to users (cont.)
The register view The register template Restricting access to logged-in users
The register view needs to display a blank registration form when The register.html template displays the registration form in Some pages are only relevant to registered users. The views for
the page is first requested, and then process completed paragraph formats. these pages can be protected by the @login_required decorator.
registration forms. A successful registration logs the user in and Any view with this decorator will automatically redirect non-logged
redirects to the home page. {% extends 'learning_logs/base.html' %} in users to an appropriate page. Here’s an example views.py file.
from django.shortcuts import render, redirect {% block content %} from django.contrib.auth.decorators import \
from django.contrib.auth import login login_required
from django.contrib.auth.forms import \ <form method='post' --snip--
UserCreationForm action="{% url 'users:register' %}">
@login_required
def register(request): {% csrf_token %} def topic(request, topic_id):
"""Register a new user.""" {{ form.as_p }} """Show a topic and all its entries."""

if request.method != 'POST': Setting the redirect URL


<button name='submit'>Register</button> The @login_required decorator sends unauthorized users to the
# Display blank registration form. <input type='hidden' name='next' login page. Add the following line to your project’s settings.py file
form = UserCreationForm() value="{% url 'learning_logs:index' %}"/> so Django will know how to find your login page.
else:
# Process completed form. </form> LOGIN_URL = 'users:login'
form = UserCreationForm(
data=request.POST)
Preventing inadvertent access
{% endblock content %} Some pages serve data based on a parameter in the URL. You
can check that the current user owns the requested data, and
if form.is_valid(): return a 404 error if they don’t. Here’s an example view.
new_user = form.save() Connecting data to users
Users will have data that belongs to them. Any model that should from django.http import Http404
# Log in, redirect to home page. be connected directly to a user needs a field connecting instances --snip--
login(request, new_user) of the model to a specific user.
return redirect( @login_required
Making a topic belong to a user def topic(request, topic_id):
'learning_logs:index') Only the highest-level data in a hierarchy needs to be directly
connected to a user. To do this import the User model, and add it """Show a topic and all its entries."""
# Display a blank or invalid form. as a foreign key on the data model. topic = Topics.objects.get(id=topic_id)
context = {'form': form} After modifying the model you’ll need to migrate the database. if topic.owner != request.user:
return render(request, You’ll need to choose a user ID to connect each existing instance raise Http404
to. --snip--
'registration/register.html', context)
from django.db import models
from django.contrib.auth.models import User Using a form to edit data
If you provide some initial data, Django generates a form
Styling your project class Topic(models.Model): with the user’s existing data. Users can then modify and
The django-bootstrap4 app allows you to use the Bootstrap """A topic the user is learning about.""" save their data.
library to make your project look visually appealing. The text = models.CharField(max_length=200)
app provides tags that you can use in your templates to date_added = models.DateTimeField( Creating a form with initial data
The instance parameter allows you to specify initial data for a form.
style individual elements on a page. Learn more at auto_now_add=True)
https://django-bootstrap4.readthedocs.io/. owner = models.ForeignKey(User, form = EntryForm(instance=entry)
on_delete=models.CASCADE)
Modifying data before saving
Deploying your project The argument commit=False allows you to make changes before
def __str__(self):
writing data to the database.
Heroku lets you push your project to a live server, making it return self.text
available to anyone with an internet connection. Heroku new_topic = form.save(commit=False)
Querying data for the current user
offers a free service level, which lets you learn the In a view, the request object has a user attribute. You can use this
new_topic.owner = request.user
deployment process without any commitment. You’ll need attribute to query for the user’s data. The filter() method then
new_topic.save()
to install a set of Heroku command line tools, and use git to pulls the data that belongs to the current user.
track the state of your project. See More cheat sheets available at
https://devcenter.heroku.com/, and click on the Python link. topics = Topic.objects.filter(
owner=request.user) ehmatthes.github.io/pcc_2e/

You might also like