Introdução
No tutorial anterior, “Como Criar um Aplicativo Django e Conectá-lo a um Banco de Dados”, abordamos como criar um banco de dados MySQL, como criar e iniciar um aplicativo Django e como conectá-lo a um banco de dados MySQL.
Neste tutorial, vamos criar os modelos do Django que definem os campos e comportamentos dos dados do aplicativo Blog que iremos armazenar. Esses modelos mapeiam os dados do seu aplicativo Django para o banco de dados. É isso que o Django usa para gerar as tabelas do banco de dados por meio de sua API de mapeamento objeto-relacional (ORM), referida como “modelos”.
Pré-requisitos
Este tutorial faz parte da série de desenvolvimento do Django e é uma continuação dessa série.
Se você não acompanhou esta série, estamos fazendo as seguintes suposições:
- Você tem o Django na versão 4 ou superior instalado.
- Você conectou seu aplicativo Django a um banco de dados. Estamos usando MySQL, e você pode alcançar essa conexão seguindo a segunda parte da série Django, “Como Criar um Aplicativo Django e Conectá-lo a um Banco de Dados.”
- Você está trabalhando com um sistema operacional baseado em Unix, preferencialmente um servidor em nuvem Ubuntu 22.04, pois este é o sistema que testamos. Se você deseja configurar o Django em um ambiente semelhante, consulte nosso tutorial, “Como Instalar o Django e Configurar um Ambiente de Desenvolvimento no Ubuntu 22.04.”
Como este tutorial trata principalmente de modelos Django, você pode acompanhar mesmo se tiver uma configuração um pouco diferente.
Passo 1 — Criar Aplicativo Django
Para ser consistente com a filosofia de modularidade do Django, criaremos um aplicativo Django dentro de nosso projeto que contenha todos os arquivos necessários para criar o site do blog.
Sempre que começarmos a trabalhar em Python e Django, devemos ativar nosso ambiente virtual Python e entrar no diretório raiz de nosso aplicativo. Se você seguiu a série, pode fazer isso digitando o seguinte.
- cd ~/my_blog_app
- . env/bin/activate
- cd blog
A partir daí, vamos executar este comando:
- python manage.py startapp blogsite
Isso criará nosso aplicativo juntamente com um diretório blogsite
.
Neste ponto da série de tutoriais, você terá a seguinte estrutura de diretório para o seu projeto:
my_blog_app/
└── blog
├── blog
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-38.pyc
│ │ ├── settings.cpython-38.pyc
│ │ ├── urls.cpython-38.pyc
│ │ └── wsgi.cpython-38.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── blogsite
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py
O arquivo em que vamos nos concentrar para este tutorial será o arquivo models.py
, que está no diretório blogsite
.
Passo 2 — Adicionar o Modelo de Posts
Primeiro, precisamos abrir e editar o arquivo models.py
para que contenha o código para gerar um modelo Post
. Um modelo Post
contém os seguintes campos do banco de dados:
título
— O título da postagem do blog.slug
— Onde os URLs válidos são armazenados e gerados para páginas da web.conteúdo
— O conteúdo textual da postagem do blog.criado_em
— A data em que a postagem foi criada.autor
— A pessoa que escreveu a postagem.
Agora, vá para o diretório onde o arquivo models.py
está localizado.
- cd ~/my_blog_app/blog/blogsite
Use o comando cat
para mostrar o conteúdo do arquivo em seu terminal.
- cat models.py
O arquivo deve ter o seguinte código, que importa modelos, junto com um comentário descrevendo o que deve ser colocado neste arquivo models.py
.
from django.db import models
# Crie seus modelos aqui.
Usando o seu editor de texto favorito, adicione o seguinte código ao arquivo models.py
. Vamos usar o nano
como nosso editor de texto, mas sinta-se à vontade para usar o que preferir.
- nano models.py
Dentro deste arquivo, o código para importar a API de modelos já está adicionado, podemos prosseguir e excluir o comentário que segue. Em seguida, vamos importar slugify
para gerar slugs a partir de strings, o User
do Django para autenticação e o reverse
de django.urls
para nos dar maior flexibilidade na criação de URLs.
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
Em seguida, adicione o método de classe na classe de modelo que estaremos chamando de Post
, com os seguintes campos de banco de dados: title
, slug
, content
, created_on
e author
. Adicione-os abaixo de suas declarações de importação.
...
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()
Depois, vamos adicionar funcionalidade para a geração do URL e a função para salvar o post. Isso é crucial, porque cria um link único para corresponder ao nosso post único.
...
def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
Agora, precisamos dizer ao modelo como as postagens devem ser ordenadas e exibidas na página da web. A lógica para isso será adicionada a uma classe Meta
interna aninhada. A classe Meta
geralmente contém outra lógica importante do modelo que não está relacionada à definição de campo do banco de dados.
...
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
Por fim, vamos adicionar o modelo Comment
a este arquivo. Isso envolve adicionar outra classe chamada Comment
com models.Models
em sua assinatura e os seguintes campos de banco de dados definidos:
name
— O nome da pessoa que está postando o comentário.email
— O endereço de e-mail da pessoa que está postando o comentário.text
— O texto do próprio comentário.post
— A postagem na qual o comentário foi feito.created_on
— O horário em que o comentário foi criado.
...
class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
Neste ponto, o arquivo models.py
estará completo. Certifique-se de que o seu arquivo models.py
corresponda ao seguinte:
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()
def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
Asegure-se de salvar e fechar o arquivo. Se estiver usando o nano, pode fazê-lo digitando CTRL
e X
, depois Y
, e então ENTER
.
Com o arquivo models.py
configurado, podemos prosseguir para atualizar nosso arquivo settings.py
.
Passo 3 — Atualizar Configurações
Agora que adicionamos modelos à nossa aplicação, devemos informar ao nosso projeto a existência do aplicativo blogsite
que acabamos de adicionar. Fazemos isso adicionando-o à seção INSTALLED_APPS
no arquivo settings.py
.
Navegue até o diretório onde o seu arquivo settings.py
está localizado.
- cd ~/my_blog_app/blog/blog
A partir daqui, abra o seu arquivo settings.py
, com o nano, por exemplo.
- nano settings.py
Com o arquivo aberto, adicione o aplicativo blogsite
à seção INSTALLED_APPS
do arquivo, conforme indicado abaixo.
# Definição de Aplicativos
INSTALLED_APPS = [
'blogsite',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Com o aplicativo blogsite
adicionado, você pode salvar e sair do arquivo.
Neste ponto, estamos prontos para prosseguir e aplicar essas mudanças.
Passo 4 — Fazer Migrações
Com nossos modelos Post
e Comment
adicionados, o próximo passo é aplicar essas alterações para que o esquema do nosso banco de dados MySQL
as reconheça e crie as tabelas necessárias.
Primeiro, devemos agrupar nossas alterações de modelo em arquivos de migração individuais usando o comando makemigrations
. Esses arquivos são semelhantes aos commits
em um sistema de controle de versão como o Git.
Agora, se você navegar para ~/my_blog_app/blog/blogsite/migrations
e executar ls
, você notará que há apenas um arquivo __init__.py
. Isso mudará assim que adicionarmos as migrações.
Mude para o diretório do blog usando cd
, assim:
- cd ~/my_blog_app/blog
Em seguida, execute o comando makemigrations
em manage.py
.
- python manage.py makemigrations
Você deverá receber a seguinte saída na sua janela do terminal:
OutputMigrations for 'blogsite':
blogsite/migrations/0001_initial.py
- Create model Post
- Create model Comment
Lembre-se, quando navegamos para /~/my_blog_app/blog/blogsite/migrations
e só havia o arquivo __init__.py
? Se agora cd
voltarmos para esse diretório, vamos notar que dois itens foram adicionados: __pycache__
e 0001_initial.py
. O arquivo 0001_initial.py
foi gerado automaticamente quando você executou makemigrations
. Um arquivo semelhante será gerado sempre que você executar makemigrations
.
Execute less 0001_initial.py
do diretório em que ele se encontra se você quiser ler o que o arquivo contém.
Agora navegue para ~/my_blog_app/blog
:
- cd ~/my_blog_app/blog
Já que fizemos um arquivo de migração, devemos aplicar as alterações descritas nesses arquivos ao banco de dados usando o comando migrate
. Mas primeiro, vamos verificar quais migrações existem atualmente, usando o comando showmigrations
.
- python manage.py showmigrations
Outputadmin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
blogsite
[ ] 0001_initial
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial
Você vai notar que todas as migrações estão marcadas, exceto aquela para 0001_initial
que acabamos de criar com os modelos Post
e Comment
.
Agora vamos verificar quais declarações SQL
serão executadas assim que fizermos as migrações, usando o seguinte comando. Ele recebe a migração e o título da migração como argumento:
- python manage.py sqlmigrate blogsite 0001_initial
Abaixo está revelada a consulta SQL
real sendo feita nos bastidores.
Output--
-- Criar modelo Post
--
CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL);
--
-- Criar modelo Comment
--
CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `post_id` integer NOT NULL);
ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);
Vamos agora realizar as migrações para que sejam aplicadas ao nosso banco de dados MySQL.
- python manage.py migrate
Vamos receber a seguinte saída:
OutputOperations to perform:
Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
Applying blogsite.0001_initial... OK
Você aplicou com sucesso suas migrações agora.
É importante ter em mente que existem três ressalvas para migrações do Django com o MySQL como seu backend, conforme indicado na documentação do Django.
- Falta de suporte para transações em torno de operações de alteração de esquema. Em outras palavras, se uma migração falhar ao ser aplicada com sucesso, você terá que desfazer manualmente as alterações feitas para tentar outra migração. Não é possível reverter para um ponto anterior, antes de quaisquer alterações feitas na migração que falhou.
- Para a maioria das operações de alteração de esquema, o MySQL reescreverá completamente as tabelas. No pior caso, a complexidade de tempo será proporcional ao número de linhas na tabela para adicionar ou remover colunas. De acordo com a documentação do Django, isso pode ser tão lento quanto um minuto por milhão de linhas.
- No MySQL, existem limites pequenos no comprimento dos nomes de colunas, tabelas e índices. Também há um limite no tamanho combinado de todas as colunas e coberturas de índice. Enquanto alguns outros backends podem suportar limites mais altos criados no Django, os mesmos índices falharão ao serem criados com um backend MySQL em funcionamento.
Para cada banco de dados que você considerar para uso com o Django, certifique-se de ponderar as vantagens e desvantagens de cada um.
Etapa 5 — Verificar o Esquema do Banco de Dados
Com as migrações concluídas, devemos verificar a geração bem-sucedida das tabelas MySQL que criamos por meio de nossos modelos do Django.
Para fazer isso, execute o seguinte comando no terminal para fazer login no MySQL. Usaremos o djangouser
que criamos no tutorial anterior.
- mysql blog_data -u djangouser
Agora, selecione nosso banco de dados blog_data
. Se você não sabe qual banco de dados está usando, pode mostrar todos os bancos de dados com SHOW DATABASES;
em SQL.
- USE blog_data;
Então digite o seguinte comando para visualizar as tabelas.
- SHOW TABLES;
Esta consulta SQL deve revelar o seguinte:
Output+----------------------------+
| Tables_in_blog_data |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| blogsite_comment |
| blogsite_post |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
12 rows in set (0.01 sec)
Entre as tabelas estão blogsite_comment
e blogsite_post
. Estes são os modelos que acabamos de fazer nós mesmos. Vamos validar que eles contêm os campos que definimos.
- DESCRIBE blogsite_comment;
Output+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(42) | NO | | NULL | |
| email | varchar(75) | NO | | NULL | |
| website | varchar(200) | YES | | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| post_id | int | NO | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
- DESCRIBE blogsite_post;
Output+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| slug | varchar(255) | NO | UNI | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| author | longtext | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
Verificamos que as tabelas do banco de dados foram geradas com sucesso a partir de nossas migrações de modelo do Django.
Você pode sair do MySQL com CTRL
+ D
e quando estiver pronto para deixar seu ambiente Python, você pode executar o comando deactivate
:
- deactivate
Desativar seu ambiente de programação o levará de volta ao prompt de comando do terminal.
Conclusão
Neste tutorial, adicionamos com sucesso modelos para funcionalidades básicas em uma aplicação web de blog. Você aprendeu como codificar models
, como funcionam as migrations
e o processo de traduzir os models
do Django para tabelas de banco de dados MySQL
reais.
Source:
https://www.digitalocean.com/community/tutorials/how-to-create-django-models