Como Criar Modelos no Django

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, criaremos os modelos Django que definem os campos e comportamentos dos dados do aplicativo Blog que estaremos armazenando. Esses modelos mapeiam os dados do seu aplicativo Django para o banco de dados. É o 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 Django e é uma continuação dessa série.

Se você não acompanhou esta série, estamos fazendo as seguintes suposições:

Como este tutorial lida principalmente com modelos do Django, você pode acompanhar mesmo que tenha 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 do 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 do nosso aplicativo. Se você seguiu a série, pode fazer isso digitando o seguinte.

  1. cd ~/my_blog_app
  2. . env/bin/activate
  3. cd blog

A partir daí, vamos executar este comando:

  1. 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órios 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.

Etapa 2 — Adicionar o Modelo de Postagens

Primeiro, precisamos abrir e editar o arquivo models.py para que contenha o código para gerar um modelo de Post. Um modelo de Post contém os seguintes campos de banco de dados:

  • title — O título da postagem do blog.
  • slug — Onde URLs válidos são armazenados e gerados para páginas da web.
  • content — O conteúdo textual da postagem do blog.
  • created_on — A data em que a postagem foi criada.
  • author — A pessoa que escreveu a postagem.

Agora, mova-se para o diretório onde o arquivo models.py está localizado.

  1. cd ~/my_blog_app/blog/blogsite

Use o comando cat para mostrar o conteúdo do arquivo no seu terminal.

  1. cat models.py

O arquivo deve ter o seguinte código, que importa modelos, juntamente com um comentário descrevendo o que deve ser colocado neste arquivo models.py.

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 você pode usar o que preferir.

  1. 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 o segue. Em seguida, vamos importar slugify para gerar slugs a partir de strings, o User do Django para autenticação e reverse de django.urls para nos dar maior flexibilidade na criação de URLs.

models.py
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 chamaremos 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.

models.py
...
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()

Em seguida, adicionaremos funcionalidades para a geração da URL e a função para salvar a postagem. Isso é crucial, pois cria um link único para corresponder à nossa postagem única.

models.py
...
    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 interna aninhada chamada Meta. A classe Meta geralmente contém outras lógicas importantes do modelo que não estão relacionadas à definição de campo do banco de dados.

models.py
...
    class Meta:
        ordering = ['created_on']

        def __unicode__(self):
            return self.title

Finalmente, adicionaremos 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 com a qual o comentário foi feito.
  • created_on — O horário em que o comentário foi criado.
models.py
...
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, models.py estará completo. Certifique-se de que seu arquivo models.py corresponda ao seguinte:

models.py
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)


Lembre-se de salvar e fechar o arquivo. Se estiver usando o nano, pode fazer isso digitando CTRL e X, depois Y, e, por fim, ENTER.

Com o arquivo models.py configurado, podemos prosseguir para atualizar nosso arquivo settings.py.

Passo 3 — Atualize as 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 em settings.py.

Navegue até o diretório onde seu arquivo settings.py está localizado.

  1. cd ~/my_blog_app/blog/blog

A partir daqui, abra seu arquivo settings.py, por exemplo, com o nano.

  1. nano settings.py

Com o arquivo aberto, adicione seu aplicativo blogsite à seção INSTALLED_APPS do arquivo, conforme indicado abaixo.

settings.py
# Definição do aplicativo
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 de banco de dados MySQL reconheça-os e crie as tabelas necessárias.

Primeiro, devemos empacotar 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, como este:

  1. cd ~/my_blog_app/blog

Em seguida, execute o comando makemigrations em manage.py.

  1. python manage.py makemigrations

Você deverá então receber a seguinte saída na janela do terminal:

Output
Migrations 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 voltarmos para esse diretório usando o comando cd, notaremos que dois itens foram adicionados: __pycache__ e 0001_initial.py. O arquivo 0001_initial.py foi gerado automaticamente quando você executou o comando makemigrations. Um arquivo semelhante será gerado sempre que você executar makemigrations.

Execute less 0001_initial.py no diretório em que está, se quiser ler sobre o que o arquivo contém.

Agora navegue até ~/my_blog_app/blog:

  1. cd ~/my_blog_app/blog

Como criamos 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.

  1. python manage.py showmigrations
Output
admin [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ê 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 quando fizermos as migrações, usando o seguinte comando. Ele recebe a migração e o título da migração como argumento:

  1. python manage.py sqlmigrate blogsite 0001_initial

Abaixo está 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.

  1. python manage.py migrate

Vamos receber a seguinte saída:

Output
Operations to perform: Apply all migrations: admin, auth, blogsite, contenttypes, sessions Running migrations: Applying blogsite.0001_initial... OK

Você aplicou suas migrações com sucesso.

É importante ter em mente que existem três ressalvas para as 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 temporal 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. Há também um limite no tamanho combinado de todas as colunas e capas 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ê considera para uso com o Django, certifique-se de ponderar as vantagens e desvantagens de cada um.

Passo 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. Vamos usar o djangouser que criamos no tutorial anterior.

  1. 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.

  1. USE blog_data;

Em seguida, digite o seguinte comando para visualizar as tabelas.

  1. 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. Esses são os modelos que acabamos de criar. Vamos validar se eles contêm os campos que definimos.

  1. 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)
  1. 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 das migrações do nosso modelo Django.

Você pode sair do MySQL com CTRL + D e quando estiver pronto para sair do ambiente Python, pode executar o comando deactivate:

  1. deactivate

Desativar seu ambiente de programação irá colocá-lo de volta ao prompt de comando do terminal.

Conclusão

No tutorial, nós 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 tradução de modelos Django para tabelas reais de banco de dados MySQL.

Source:
https://www.digitalocean.com/community/tutorials/how-to-create-django-models