💻
Dicas de Django
  • Dica 1 - Django boilerplate e cookiecutter-django
  • Dica 1.1 - Django boilerplate
  • Dica 2 - Django extensions
  • Dica 3 - Django bulk_create e django-autoslug
  • Dica 4 - Django Admin personalizado
  • Dica 5 - Django Admin Date Range filter
  • Dica 6 - Geradores de senhas randômicas - uuid, hashids, secrets
  • Dica 7 - Rodando o ORM do Django no Jupyter Notebook
  • Dica 8 - Conhecendo o Django Debug Toolbar
  • Dica 9 - Escondendo suas senhas python-decouple
  • Dica 10 - Prototipagem de web design (Mockup)
  • Dica 11 - Bootstrap e Bulma + Colorlib
  • Dica 12 - Imagens: pexels e unsplash
  • Dica 13 - Cores
  • Dica 14 - Herança de Templates e Arquivos estáticos
  • Dica 15 - Busca por data no frontend
  • Dica 16 - Filtros com django-filter
  • Dica 17 - Criando comandos personalizados
  • Dica 18 - bulk_create e bulk_update
  • Dica 19 - Criando Issues por linha de comando com a api do github
  • Dica 20 - api github e click
  • Dica 21 - Criando issues por linha de comando com gitlab cli
  • 022-criando-issues-por-linha-de-comando-com-bitbucket-cli
  • Dica 23 - Diferença entre JSON dump, dumps, load e loads
  • Dica 24 - Barra de progresso
  • Dica 25 - Rodando Shell script dentro do Python
  • Dica 26 - Rodando Python dentro do Shell script
  • Dica 27 - Retornando os nomes dos campos do model
  • Dica 28 - Admin: Usando short description
  • Dica 29 - Django Admin: Criando actions no Admin
  • Dica 30 - Django Admin: Editando direto na listview do Admin
  • Dica 31 - Django Admin: Pegando usuário logado no Admin
  • Dica 32 - Django Admin: Sobreescrevendo os templates do Admin
  • Dica 33 - Github cli
  • Dica 34 - Django: custom template tags
  • Dica 35 - Django: passando usuário logado no formulário
  • Dica 36 - Django: visualizando seus modelos com graph models
  • Dica 37 - Faker
  • Dica 38 - Django: Paginação + Filtros
  • Dica 39 - Django Admin: display decorator (Django 3.2+)
  • Dica 40 - Formulários: date, datetime, duration e templatetags de data
  • Dica 41 - django-seed
  • Dica 42 - Custom context processors
  • Dica 43 - django-admin-rangefilter
  • Dica 44 - Django: F() expression
  • Dica 45 - DRF: Scaffold django apis - Django REST framework
  • Dica 46 - DRF: drf-yasg - Yet another Swagger generator
  • Dica 47 - DRF: djoser - Django REST framework
  • Dica 48 - DRF: Reset de Senha com djoser - Django REST framework
  • Dica 49 - DRF: Autenticação via JWT com djoser - Django REST framework
  • Dica 50 - DRF: Django CORS headers
  • Dica 51 - DRF: paginação
  • Dica 52 - DRF: django-filter
  • Dica 53 - DRF: Criando subrota com action
  • 54-django-extensions-mais-comandos
  • Dica 55 - Rodando Django em https localmente com runserver_plus
  • Dica 56 - Django inlineformset_factory + HTMX
  • Dica 57 - Criando API com Django SEM DRF
  • Dica 58 - Rodando PostgreSQL com Docker + Portainer + pgAdmin + Django local para desenvolvimento
  • Dica 59 - Django: Busca por palavras acentuadas ou sem acento
  • Dica 60 - Django: Adicionando atributos extras no formulário
  • Dica 01 - Criando Issues com API do Github (Linux)
  • Dica 02 - Usando http.server
  • Dica 03 - Criando um template com Bulma CSS
  • Dica 04 - Criando um template com Tailwind CSS
  • Dica 05 - htmx simples
  • Dica 06 - Criando o projeto Django
  • Dica 07 - PostgreSQL, pgAdmin e MailHog com docker-compose
  • Dica 08 - Aplicando isort e autopep8
  • Dica 09 - Aplicando djhtml
  • Dica 10 - Criando Makefile
  • Dica 11 - Criando Landpage de produtos
  • 072-012-fale-co-nosco-form-email
  • Dica 13 - Dashboard com Django e Tailwind CSS
  • Dica 14 - Django Custom User com e-mail
  • Dica 15 - Login com e-mail no Django
  • Dica 16 - Logout
  • Dica 17 - Cadastro de Usuários no Django
  • Dica 18 - Esqueci a senha
  • Dica 19.1 - Modelagem - OneToMany - Um pra Muitos - ForeignKey - Chave Estrangeira
  • Dica 19.2 - Modelagem - OneToOne - Um pra Um
  • Dica 19.3 - Modelagem - ManyToMany - Muitos pra Muitos
  • Dica 19.4 - Modelagem - Abstract Inheritance - Herança Abstrata
  • Dica 19.5 - Modelagem - Multi-table Inheritance - Herança Multi-tabela
  • Dica 19.6 - Modelagem - Proxy Model
  • Dica 19.7 - Modelagem - Resumo
  • Dica 20 - Templates
  • Dica 21 - Tentativas de Login
  • Dica 22 - Validação
  • Dica 23 - CRUD de produtos
  • Dica 24 - Alpine.js e Django
  • 091-25-dica-queryset
  • Dica 26 - Paginação e Breadcrumb
  • Dica 27 - Signals
  • Dica 28 - Gerando dados aleatórios com Faker - faker-commerce
  • Dica 29 - Importando CSV
  • 096-30-import-csv-inmemoryuploadedfile
  • Dica 31 - Importando CSV com Pandas
  • Dica 32 - Importando CSV com Dask
  • Dica 33 - Importando XLSX com OpenPyXL
  • 100-34-export-csv
  • Dica 35 - Exportando XLSX mais rápido com pyexcelerate
  • Dica 36 - Exportando CSV e XLSX pelo front no projeto
  • Novidades do Django 5.1
  • Django Router
  • 105-django-52
Powered by GitBook
On this page
  • Leia
  • ORM - Object Relational Mapping
  • Rodando comandos direto no PostgreSQL.
  • Rodando comandos pelo Django
  • Criando uma nova app
  • OneToMany - Um pra Muitos - ForeignKey - Chave Estrangeira
  • Diagrama ER
  • Inserindo dados com django-seed
  • ORM
  • PostgreSQL e pgAdmin no Docker
  • DBeaver e CloudBeaver
  • CloudBeaver
  • pgAdmin 4
  • DBeaver
  • Jupyter Notebook

Was this helpful?

Dica 19.1 - Modelagem - OneToMany - Um pra Muitos - ForeignKey - Chave Estrangeira

PreviousDica 18 - Esqueci a senhaNextDica 19.2 - Modelagem - OneToOne - Um pra Um

Last updated 2 years ago

Was this helpful?

Leia

ORM - Object Relational Mapping

Rodando comandos direto no PostgreSQL.

docker-compose up -d

docker container exec -it dicas_de_django_db psql

\l  # lista os bancos
\c dicas_de_django_db  # conecta em dicas_de_django_db
\dt  # lista as tabelas

SELECT first_name, last_name, email FROM accounts_user;
SELECT * FROM accounts_user;

\q  # sair

Rodando comandos pelo Django

Dentro do container

docker container exec -it dicas_de_django_app python manage.py shell_plus

User.objects.all()

Caso dê erro no container faça

docker-compose up --build  -d

docker container exec -it dicas_de_django_app python manage.py shell_plus

User.objects.all()

Fora do container

python manage.py shell_plus

User.objects.all()

Fazendo mais algumas queries.

>>> users = User.objects.values('first_name', 'last_name', 'email')
>>> users
<QuerySet [{'first_name': '', 'last_name': '', 'email': 'admin@email.com'}, {'first_name': 'Regis', 'last_name': 'Santos', 'email': 'regis@email.com'}]>
>>> print(users.query)
SELECT "accounts_user"."first_name", "accounts_user"."last_name", "accounts_user"."email" FROM "accounts_user"

>>> users = User.objects.all()
>>> users
<QuerySet [<User: admin@email.com>, <User: regis@email.com>]>
>>> for user in users:
...     print(user)
... 
admin@email.com
regis@email.com

>>> for user in users:
...     print(user.first_name, user.email)
... 
 admin@email.com
Regis regis@email.com

E agora vamos aplicar um filtro.

>>> user = User.objects.filter(email__icontains='regis').values('first_name', 'email')
>>> user
<QuerySet [{'first_name': 'Regis', 'email': 'regis@email.com'}]>
>>> print(user.query)
SELECT "accounts_user"."first_name", "accounts_user"."email" FROM "accounts_user" WHERE UPPER("accounts_user"."email"::text) LIKE UPPER(%regis%)

Criando uma nova app

Vamos criar uma nova app chamada bookstore.

cd backend
python ../manage.py startapp bookstore
cd ..

Adicione em INSTALLED_APPS

# settings.py
INSTALLED_APPS = [
    ...
    'backend.bookstore',
]

Edite urls.py

# urls.py
...
path('', include('backend.bookstore.urls', namespace='bookstore')),

Edite bookstore/apps.py

# bookstore/apps.py
...
name = 'backend.bookstore'

Crie bookstore/urls.py

# bookstore/urls.py
from django.urls import path

app_name = 'bookstore'

urlpatterns = [

]

OneToMany - Um pra Muitos - ForeignKey - Chave Estrangeira

É o relacionamento onde usamos chave estrangeira, conhecido como ForeignKey.

Um cliente pode fazer vários pedidos, então para reproduzir o esquema acima, usamos o seguinte código:

# bookstore/models.py
from django.db import models


class Customer(models.Model):
    first_name = models.CharField('nome', max_length=100)
    last_name = models.CharField('sobrenome', max_length=255, null=True, blank=True)  # noqa E501
    email = models.EmailField('e-mail', max_length=50, unique=True)
    active = models.BooleanField('ativo', default=True)

    class Meta:
        ordering = ('first_name',)
        verbose_name = 'cliente'
        verbose_name_plural = 'clientes'

    @property
    def full_name(self):
        return f'{self.first_name} {self.last_name or ""}'.strip()

    def __str__(self):
        return self.full_name


STATUS = (
    ('p', 'Pendente'),
    ('a', 'Aprovado'),
    ('c', 'Cancelado'),
)


class Ordered(models.Model):
    status = models.CharField(max_length=1, choices=STATUS, default='p')
    customer = models.ForeignKey(
        Customer,
        on_delete=models.SET_NULL,
        verbose_name='cliente',
        related_name='ordereds',
        null=True,
        blank=True
    )
    created = models.DateTimeField(
        'criado em',
        auto_now_add=True,
        auto_now=False
    )

    class Meta:
        ordering = ('-pk',)
        verbose_name = 'ordem de compra'
        verbose_name_plural = 'ordens de compra'

    def __str__(self):
        if self.customer:
            return f'{str(self.pk).zfill(3)}-{self.customer}'

        return f'{str(self.pk).zfill(3)}'
# bookstore/admin.py
from django.contrib import admin

from .models import Customer, Ordered


@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'email', 'active')
    search_fields = ('first_name', 'last_name')
    list_filter = ('active',)


@admin.register(Ordered)
class OrderedAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'customer', 'status')
    search_fields = (
        'customer__first_name',
        'customer__last_name',
        'customer__email',
    )
    list_filter = ('status',)
    date_hierarchy = 'created'
python manage.py makemigrations
python manage.py migrate

Diagrama ER

Inserindo dados com django-seed

pip install django-seed

pip freeze | grep django-seed >> requirements.txt

Edite settings.py

# settings.py
INSTALLED_APPS = [
    ...
    'django_seed',
    ...
]

Gerando os dados

python manage.py seed bookstore --number=3

ORM

python manage.py shell_plus


from backend.bookstore.models import Customer, Ordered

customers = Customer.objects.all()

for customer in customers:
    print(customer)

ordereds = Ordered.objects.all()

for ordered in ordereds:
    print(ordered)

PostgreSQL e pgAdmin no Docker

Vamos usar o PostgreSQL rodando no Docker.

docker-compose up -d

Podemos ver tudo pelo pgAdmin, ou

docker container exec -it dicas_de_django_db psql

As tabelas

\c dicas_de_django_db  # conecta no banco dicas_de_django_db
\dt    # mostra todas as tabelas

Os registros

SELECT * FROM bookstore_ordered;

id | status |        created         | customer_id 
----+--------+------------------------+-------------
  1 | p      | 1976-01-05 07:04:10+00 |           1
  2 | p      | 2021-02-09 06:08:27+00 |           3
  3 | p      | 1986-08-13 02:54:02+00 |           1

Schema

SELECT column_name, data_type FROM information_schema.columns WHERE TABLE_NAME = 'bookstore_ordered';
 column_name |        data_type         
-------------+--------------------------
 id          | bigint
 created     | timestamp with time zone
 customer_id | bigint
 status      | character varying
(4 rows)

DBeaver e CloudBeaver

CloudBeaver

https://github.com/dbeaver/cloudbeaver/wiki/Run-Docker-Container

https://cloudbeaver.io/doc/cloudbeaver.pdf

Edite o docker-compose.yml

  cloudbeaver:
    container_name: dicas_de_django_cloudbeaver
    image: dbeaver/cloudbeaver:latest
    volumes:
       - /var/cloudbeaver/workspace:/opt/cloudbeaver/workspace
    ports:
      - 5052:8978
    networks:
      - dicas-de-django-network

E rode

docker-compose up -d

Entre no Portainer e entre no CloudBeaver.

Login e senha

Login: cbadmin
Pass: admin

Conexão com dicas_de_django_db.

pgAdmin 4

User: admin
Password: admin
Port: 5432
Database: localhost
Username: postgres
Password: postgres

DBeaver

Host: 0.0.0.0
Port: 5431
Database: dicas_de_django_db
Username: postgres
Password: postgres

Jupyter Notebook

Para instalar o Jupyter digite

pip install jupyter

E para rodar digite

python manage.py shell_plus --notebook

Quando você tentar rodar

Customer.objects.all()

Você vai ter este erro

SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.

Então edite o settings.py

import os

os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"

Mas o código completo deve ser

from backend.bookstore.models import Customer, Ordered
Customer.objects.all()

adam = Customer.objects.create(first_name='Adam', email='adam@email.com')
james = Customer.objects.create(first_name='James', email='james@email.com')

Customer.objects.all()

Ordered.objects.create(customer=adam)
Ordered.objects.create(customer=adam)
Ordered.objects.create(customer=james)
Ordered.objects.create(customer=james)
Ordered.objects.create(customer=james)

ordereds = Ordered.objects.all()

for ordered in ordereds:
    print(ordered)
    print(ordered.status)
    print(ordered.get_status_display())
    print(ordered.customer)
    print(ordered.customer.email)

Ou seja, a partir da ordem de compra conseguimos ver o cliente.

E como fazemos para a partir do cliente, ver as ordens de compra dele?

adam.ordereds.all()
james.ordereds.all()

Ou seja, pegamos os dados pelo related_name.

Leia .

Ilustração feita com .

QuerySet API reference #icontains
excalidraw.com
https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
01_fk.png