Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: translate the understand-django-book into portuguese #154

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
bb2e476
docs(pt): prepare ground to translate understanding django book
nazarepiedady Mar 25, 2023
e9ebb0a
docs(pt): translate `understand-django/_index.pt.md`
nazarepiedady Mar 25, 2023
0c7165b
docs(pt): translate `understand-django/browser-to-django.pt.md`
nazarepiedady Apr 11, 2023
2517934
chore: format `understand-django/2020-03-03-views-on-views.pt.md`
nazarepiedady May 5, 2023
1dc299a
chore: format `understand-django/2020-04-02-templates-user-interfaces…
nazarepiedady May 5, 2023
f87773a
chore: format `understand-django/2020-05-05-user-interaction-forms.pt…
nazarepiedady May 5, 2023
ada204e
chore: format `understand-django/2020-06-25-store-data-with-models.pt…
nazarepiedady May 5, 2023
37c4291
chore: format `understand-django/2020-08-26-administer-all-the-things…
nazarepiedady May 5, 2023
d2b7ecf
chore: format `understand-django/2020-09-29-anatomy-of-an-application…
nazarepiedady May 5, 2023
0473f4a
chore: format `understand-django/2020-11-04-user-authentication.pt.md`
nazarepiedady May 5, 2023
8ecff8a
chore: format `understand-django/2020-12-16-middleware-do-you-go.pt.md`
nazarepiedady May 5, 2023
7ef4adb
chore: format `understand-django/2021-01-06-serving-static-files.pt.md`
nazarepiedady May 5, 2023
e07f12b
chore: format `understand-django/2021-02-22-test-your-apps.pt.md`
nazarepiedady May 5, 2023
c060ee2
chore: format `understand-django/2021-03-23-deploy-site-live.pt.md`
nazarepiedady May 5, 2023
e21fd63
chore: format `understand-django/2021-05-21-sessions.pt.md`
nazarepiedady May 5, 2023
8a60378
chore: format `understand-django/2021-07-15-settings.pt.md`
nazarepiedady May 5, 2023
51d2f32
chore: format `understand-django/2021-09-14-media-files.pt.md`
nazarepiedady May 5, 2023
6f35456
chore: format `understand-django/2021-11-04-command-apps.pt.md`
nazarepiedady May 5, 2023
bda72a1
chore: format `understand-django/2022-01-19-go-fast.pt.md`
nazarepiedady May 5, 2023
9dbfa20
chore: format `understand-django/2022-03-10-secure-apps.pt.md`
nazarepiedady May 5, 2023
7d2ca7c
chore: format `understand-django/2022-05-31-debugging-tips-techniques…
nazarepiedady May 5, 2023
bfff483
docs(pt): translate `understand-django/urls-lead-way.pt.md`
nazarepiedady Jun 9, 2023
5d02566
docs(pt): translate `understand-django/views-on-views.pt.md`
nazarepiedady Jun 25, 2023
e800413
docs(pt): translate `understand-django/templates-user-interfaces.pt.md`
nazarepiedady Jul 12, 2023
62e6a22
docs(pt): translate `understand-django/user-interaction-forms.pt.md`
nazarepiedady Aug 30, 2023
5a0e2aa
docs(pt): translate `understand-django/store-data-with-models.pt.md`
nazarepiedady Sep 21, 2023
24e1c14
docs(pt): translate `understand-django/administer-all-the-things.pt.md`
nazarepiedady Oct 30, 2023
64fc365
Merge branch 'main' into understand-django-book-pt
mblayman Feb 21, 2024
e4cbbd1
Merge branch 'main' into understand-django-book-pt
mblayman Feb 23, 2024
8ab352a
Merge branch 'main' into understand-django-book-pt
mblayman Feb 26, 2024
cfde7f3
docs(pt): translate `2020-09-29-anatomy-of-an-application.pt.md`
nazarepiedady Feb 28, 2024
34aef52
Merge branch 'main' into understand-django-book-pt
mblayman Mar 1, 2024
b2ec050
Merge branch 'main' into understand-django-book-pt
mblayman Mar 4, 2024
0106a85
Merge branch 'main' into understand-django-book-pt
mblayman Mar 11, 2024
29c8d12
Merge branch 'main' into understand-django-book-pt
mblayman Mar 19, 2024
b46ff3e
Merge branch 'main' into understand-django-book-pt
mblayman Mar 28, 2024
4e6ab5c
docs(pt): translate `2020-11-04-user-authentication.pt.md`
nazarepiedady May 7, 2024
1b870fa
Merge branch 'main' into understand-django-book-pt
mblayman May 10, 2024
5f57d26
docs(pt): translate and add `2020-12-16-middleware-do-you-go.pt.md`
nazarepiedady Jun 13, 2024
6080f36
Merge branch 'main' into understand-django-book-pt
mblayman Jun 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
320 changes: 320 additions & 0 deletions content/understand-django/2021-01-06-serving-static-files.pt.md

Large diffs are not rendered by default.

481 changes: 481 additions & 0 deletions content/understand-django/2021-02-22-test-your-apps.pt.md

Large diffs are not rendered by default.

366 changes: 366 additions & 0 deletions content/understand-django/2021-03-23-deploy-site-live.pt.md

Large diffs are not rendered by default.

241 changes: 241 additions & 0 deletions content/understand-django/2021-05-21-sessions.pt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
---
title: "Per-visitor Data With Sessions"
description: >-
How does Django know when a user is logged in? Where can the framework store data for a visitor on your app? In this article, we'll answer those questions and look at a storage concept in Django called sessions.
image: img/django.png
type: post
categories:
- Python
- Django
tags:
- Python
- Django
- sessions
series: "Understand Django"

---

In the last
{{< web >}}
[Understand Django]({{< ref "/understand-django/_index.pt.md" >}}) article,
{{< /web >}}
{{< book >}}
chapter,
{{< /book >}}
we saw what it takes to make your Django project live on the internet. Now, we'll get back to a more narrow topic and focus on a way Django can store data for visitors to your site. This is the kind of data that doesn't often fit well into your Django models and is called *session* data.

{{< understand-django-series-pt "sessions" >}}

## What Is A Session?

As *I* was learning Django, I'd run into sessions occasionally and accept that I didn't really understand them. They felt like magic to me. But what is a session?

> A session is a set of data that is available to users that Django can use over multiple requests.

From a development perspective, the data is different from the regular data that you would store in a database with Django models. When working with session data, you don't query the database using the ORM. Instead, you can access session content via the `request.session` attribute.

The `request.session` is a dictionary-like object. Storing data into the session is like working with any other Python dictionary:

```python
# application/view.py

from django.http import HttpResponse

def a_session_view(request):
request.session['data_to_keep'] = 'store this'
return HttpReponse('')
```

When Django stores the session data, the framework will keep the data in a JSON format. What is JSON? I've mentioned JSON in passing
{{< web >}}
in previous articles,
{{< /web >}}
{{< book >}}
in previous chapters,
{{< /book >}}
but now is a decent time to explain it. Knowing what JSON is will help you understand what happens to session data as the data is stored.

### The "What is JSON?" Sidebar

JSON is a data format. JSON is a way of describing data so that the data can be stored or transmitted. The definition of that format is listed on the official {{< extlink "https://www.json.org/json-en.html" "JSON website" >}} and can be understood in probably 10 minutes or less.

That stored data can be parsed based on the definition of the format to recreate the data at a different time or on a different computer. In general, you can view JSON as a tool to take Python dictionaries or lists and store or transmit them for use elsewhere.

The Python standard library includes a module for working with JSON data. Here's an example to give you an idea of what JSON output looks like:

```python
>>> import json
>>> data = {'hello': 'world'}
>>> json.dumps(data)
'{"hello": "world"}'
>>> json_string = json.dumps(data)
>>> parsed_data = json.loads(json_string)
>>> parsed_data
{'hello': 'world'}
>>> data == parsed_data
True
```

The `dumps` and `loads` functions transform data to and from a string, respectively (the `s` in the those function names stands for "string").

JSON is an extremely versatile format and is used all over the internet. Getting back to sessions, JSON is a good fit because there are multiple places where Django can store session data. Let's look at those next.

## Session Storage

{{< web >}}
You probably know this drill by now if you've been following this series.
{{< /web >}}
{{< book >}}
You probably know this drill by now.
{{< /book >}}
Like the template system, the ORM, and the authentication system, the session application is configurable with multiple different "engines" to store session data.

When you start a new Django project with the `startproject` command, the session engine will be set to `django.contrib.sessions.backends.db`. This is because the `SESSION_ENGINE` setting will be unset in your settings module, and Django will fall back to the default.

With this engine, Django will store session data in the database. Because `startproject` includes the `django.contrib.sessions` app in `INSTALLED_APPS`, you'd probably see the following stream by when you migrate your database for the first time:

```text
(venv) $ ./manage.py migrate
...
Running migrations:
...
Applying sessions.0001_initial... OK
```

The `Session` model stores three things:

* A session key that uniquely identifies the session in the storage engine
* The actual session data, stored in JSON format, in a `TextField`
* An expiration date for the session data

With these three fields, Django can handle the temporary storage needs for any of your site's visitors.

Why is the session engine configurable? Django's session storage is configurable to manage tradeoffs. The default storage of a database engine is a safe default and the easiest to understand. The answer to "Where is my app's session data?" is "In the database with all of my other application data."

If your site grows in popularity and usage, using the database to store sessions can become a bottleneck and limit your performance and application scaling. Additionally, the default engine creates an ever expanding set of database rows in the `Session` model's table. You can work around the second challenge by periodically running the `clearsessions` management command, but what if the performance is a problem for you?

This is where other storage engines might be better for your application. One method to improve performance is to switch to an engine that uses caching. If you have set up the caching system with a technology like {{< extlink "https://redis.io/" "Redis" >}} or {{< extlink "https://memcached.org/" "Memcached" >}}, then a lot of session load on the database can be pushed to the cache service. Caching is a topic we will explore more
{{< web >}}
in a future article,
{{< /web >}}
{{< book >}}
in a future chapter,
{{< /book >}}
so if this doesn't make too much sense right now, I apologize for referencing concepts that I haven't introduced yet. For the time being, understand that caching can improve session performance.

Another session storage engine that can remove load from a database uses the browser's cookie system. This system will certainly remove database load because the state will be stored with the browser, but this strategy comes with its own set of tradeoffs. With cookie-base storage:

* The storage could be cleared at any time by the user.
* The storage engine is limited to a small amount of data storage by the browser, based on the maximum allowed size of a cookie (commonly, only 4kB).

Choosing the right session storage engine for your application depends on what the app does. If you're in doubt, start with the default of database-backed storage, and you should be fine initially.

## How Does The Session System Identify Visitors?

When a visitor comes to your site, Django needs to associate the session data to the visitor. To do this association, Django will store a session identifier in a cookie on the user's browser.

On the first visit, the session storage engine will look for a cookie with the name `sessionid` (by default). If the application doesn't find that cookie, then the session storage will generate a random ID and ensure that the random ID doesn't conflict with any other session IDs that already exist.

From there, the storage engine will store some session data via whatever mechanism that engine uses (e.g., the database engine will create a new session row in the table).

The session ID is added to the user's browser cookies for your site's domain. Cookies are stored in a secured manner so only that browser will have access to that randomly generated value. The session ID is very long (32 characters), and the session will expire after a given length of time. These characteristics make session IDs quite secure.

Since sessions are secure and can uniquely identify a browser, what kind of data can we put in there?

## What Uses Sessions?

Sessions can store all kinds of data, but what are some real world use cases? You can look in Django's source code to find some immediate answers!

In my estimate, the most used part of Django that uses sessions heavily is the auth system. We explored the authentication and authorization system
{{< web >}}
in [User Authentication]({{< ref "/understand-django/2020-11-04-user-authentication.pt.md" >}}).
{{< /web >}}
{{< book >}}
in the User Authentication chapter.
{{< /book >}}
At the time, I mentioned in the pre-requisites that sessions were required, but I noted that sessions were an internal detail. Now that you know what sessions are about, let's see how the auth system uses them.

If you look into the session data after you've authenticated, you'll find three pieces of information:

* The user's ID (stored in `_auth_user_id`)
* The user's hash (stored in `_auth_user_hash`)
* The string name of the auth backend used (stored in `_auth_user_backend`)

Since we know that a session identifies a browser and does so securely, the auth system stores identity information into the session to tie that unique session to a unique user. When a user's browser makes an HTTP request, Django can determine the session associated with the request via the `sessionid` and gain access to the user auth data (i.e., the user's ID, hash, and auth backend). With these data elements, the auth system can determine if the request is valid and should be considered authenticated by checking against the associated auth session data.

The auth system will read which backend is used and load that backend if possible. The backend is used to load the specific user record from the ID found in the session. Finally, that user is used to check if the hash provided validates when compared to the user's hashed password (there is some extra hashing involved to ensure that the user's password hash is not stored directly in the session). If the comparison checks out, the user is authenticated and the request proceeds as an authenticated request.

You can see that the session is vital to this flow with the auth system. Without the ability to store state in the session, the user would be unable to prove who they were.

Another use of sessions is found with CSRF handling. The CSRF security features in Django
{{< web >}}
(which I mentioned in the forms article
{{< /web >}}
{{< book >}}
(which I mentioned in the forms chapter
{{< /book >}}
and we will explore more in a future topic) permit CSRF tokens to be stored in the session instead of a cookie when the `CSRF_USE_SESSIONS` setting is enabled. Django provides a safe default for CSRF tokens in cookies, but the session is an alternative storage place if you're not happy enough with the cookie configuration.

As a final example, we can look at the `messages` application. The `messages` app can store "flash" messages. A flash message is the kind of message that you'd expect to see on a single page view. For instance, if you have a message that you'd like to display to a user upon some action, you might use a flash message. Perhaps your application has some "Contact Us" form to receive customer feedback. After the customer submits the form, you might want the application to flash "Thank you for the feedback!":

```python
# application/views.py

from django.contrib import messages
from django.views.generic import FormView
from django.urls import reverse_lazy

from .forms import ContactForm

class ContactView(FormView):
form_class = ContactForm
success_url = reverse_lazy("application:index")

def form_valid(self, form):
messages.info(
self.request,
"Thank you for the feedback!"
)
return super().form_valid(form)
```

In the default setup, Django will attempt to store the flash message in the request's cookies, but, as we saw earlier, browsers constrain the maximum cookie size. If the flash messages will not fit in the request's cookies, then the `messages` app will switch to the session as a more robust alternative. Observe that this might run into problems if you are using the session's cookie storage engine!

I hope that these examples from Django's `contrib` package provide you with some ideas for how you might use sessions in your own projects.

## Summary

{{< web >}}
In this article,
{{< /web >}}
{{< book >}}
In this chapter,
{{< /book >}}
we dug into Django sessions and how you use them.

We saw:

* What sessions are and the interface they expose as `request.session`
* How JSON is used to manage session data
* Different kinds of session storage that are available to your site
* The way that Django recognizes a user's session in the browser
* Examples within `django.contrib` of how sessions get used by Django's built-in apps.

{{< web >}}
In the next article,
{{< /web >}}
{{< book >}}
In the next chapter,
{{< /book >}}
we are going to spend time focusing on settings in Django.

You'll learn about:

* Various strategies for managing your project's settings
* Django's tools to help with settings
* Tools in the larger Django ecosystem that can make your life easier

{{< web >}}
If you'd like to follow along with the series, please feel free to sign up for my newsletter where I announce all of my new content. If you have other questions, you can reach me online on Twitter where I am {{< extlink "https://twitter.com/mblayman" "@mblayman" >}}.
{{< /web >}}
&nbsp;
Loading