Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Explorando QuerySets do Django

Explorando QuerySets do Django

Uma apresentação dos principais recursos da ORM do Django através de uma aplicação de exemplo.

Labcodes Software Studio

April 04, 2018
Tweet

More Decks by Labcodes Software Studio

Other Decks in Technology

Transcript

  1. Aprendendo SQL através do Django Para quem não conhece SQL

    a ORM pode ser uma ferramenta de aprendizagem. Leia as queries que estão sendo realizadas e experimente rodá-las direto no banco. A sintaxe do SQL é simples e intuitiva, em pouco tempo você aprende o básico. Observe a quantidade de queries sendo feitas e o tempo que elas demoram.
  2. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':

    { 'class': 'logging.StreamHandler', # Loga no terminal }, }, 'loggers': { 'django': { 'handlers': ['console'], 'level': 'DEBUG', # Exibe todas as queries }, }, } Ative os logs em nível DEBUG nos settings para ver as queries no terminal e no shell do Django.
  3. Instale o Django Debug Toolbar django-debug-toolbar.readthedocs.io DEBUG_TOOLBAR_CONFIG = { 'SHOW_TOOLBAR_CALLBACK':

    lambda x: True, } Para funcionar com o Rest Framework, adicione esta configuração aos settings.
  4. Bancos de dados relacionais Em um banco relacional os dados

    são organizados em tabelas em que cada coluna define o nome e o tipo do campo que vai ser armazenado. As colunas que criam relações entre as tabelas são as chaves estrangeiras, onde uma entrada é uma referência a uma linha de outra tabela.
  5. id nome empresa_id 1 Maria 4 2 João 2 Pessoa

    id nome 2 Empresa SA 4 Company Empresa
  6. Um modelo no django é uma classe que define uma

    tabela no banco de dados. Cada atributo do modelo representa uma coluna da tabela. O tipo de campo declarado determina o tipo da coluna.
  7. Uma instância dessa classe representa uma entrada na tabela. Cada

    atributo na instância representa o valor da linha que ela representa para a respectiva coluna.
  8. class Cinema(models.Model): nome = models.CharField(max_length=50) cidade = models.ForeignKey(Cidade) CREATE TABLE

    "cinema_cinema" ( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "nome" varchar(50) NOT NULL, "cidade_id" integer NOT NULL REFERENCES "cinema_cidade" ("id") );
  9. Uma instância do modelo representa apenas uma entrada individual no

    banco, portanto os métodos de instância deveriam realizar somente operações que afetam um objeto individual. - Properties que retornam atributos da entidade ou de objetos relacionados - Métodos que verificam estados e garantem sua integridade Responsabilidades
  10. Uma instância do modelo representa apenas uma entrada no banco.

    Para acessar e manipular conjuntos de dados o Django tem as classes de Managers.
  11. Todo modelo no django tem implicitamante uma manager que é

    acessado pelo atributo objects, ele é responsável por fazer a interface entre o modelo e as operações no banco. Filme.objects.all() # Retorna todos os filmes
  12. O QuerySet do modelo é uma classe que herda de

    models.QuerySet e pode ser customizada da mesma forma que se faz com o manager. As tarefas de consulta no banco realizadas pelos managers são chamadas ao QuerySet do modelo. Um objeto QuerySet é um iterável e seus elementos são instâncias do modelo ou objetos python simples.
  13. Os métodos de consulta no banco que usamos do atributo

    objects, como all e filter, retornam chamadas de métodos com o mesmo nome do QuerySet.
  14. - get(id=10, nome='Maria') SELECT ... FROM ... table WHERE ...

    ; - first() SELECT ... FROM ... table ORDER BY ... ASC LIMIT 1; - last() SELECT ... FROM ... table ORDER BY .. DESC LIMIT 1; - earliest('nome') SELECT ... FROM ... table ORDER BY ... ASC LIMIT 1; - latest('nome') SELECT ... FROM ... table ORDER BY .. DESC LIMIT 1;
  15. Atenção! get levanta a exceção models.MultipleObjectsReturned se encontrar mais de

    uma entrada e models.DoesNotExist se não encontrar nenhuma. Os demais retornam None se não houver entradas correspondentes.
  16. - create(nome='Maria') INSERT INTO table (...) VALUES (...); - update(nome='Maria')

    UPDATE table SET <FIELD> = <VALUE>, ...; - get_or_create(nome='Maria') SELECT ... FROM ... table WHERE ... ; ??? INSERT INTO table (...) VALUES (...);
  17. - update_or_create(defaults={'idade': 30}, nome='Maria') SELECT ... FROM ... table WHERE

    ...; ??? UPDATE table SET <FIELD> = <VALUE>, ... WHERE ...; ??? INSERT INTO table (...) VALUES (...); - bulk_create([Pessoa(nome='Maria'), Pessoa(nome='João')]) INSERT INTO table (<FIELDS>) SELECT ... UNION ALL SELECT ...; - delete() DELETE FROM table WHERE ...;
  18. - all() SELECT ... FROM ... table - none() não

    acessa o banco - filter(nome='Maria') SELECT ... FROM table WHERE ... - exclude(nome='Maria') SELECT ... FROM table WHERE NOT ... - distinct() SELECT DISTINCT ... FROM ... table
  19. - order_by('nome') SELECT ... FROM ... table ORDER BY ...

    - order_by('nome').reverse() ou order_by('-nome') SELECT ... FROM ... table ORDER BY DESC ...
  20. - values('nome') SELECT ... FROM table • Seleciona todos se

    não receber argumentos • Retorna um QuerySet com dicts - values_list('nome') SELECT ... FROM table • Retorna um QuerySet com tuplas de valores - only('nome') SELECT ... FROM table - defer('nome') SELECT ... FROM table
  21. - select_related('filme') SELECT ... FROM table; INNER JOIN table2 ON

    table.table2_id = table2.id; - prefetch_related('ingressos') SELECT ... FROM table; SELECT ... FROM table2 WHERE table2.table_id IN …;
  22. Todos os métodos que retornam QuerySets podem ter chamadas encadeadas

    e a execução deles é lazzy. É possível chamar vários métodos que fazem queries diferentes, mas que só serão executadas uma vez.
  23. - iterator() SELECT ... FROM table; • Retorna um objeto

    gerador • Só realiza a query quando o primeiro elemento é acessado - exists() SELECT (1) AS "a" FROM table LIMIT 1; • Retorna um booleano
  24. - count() SELECT COUNT(*) AS "__count" FROM table; • Retorna

    um inteiro - aggregate(expression) SELECT <EXPRESSION> AS <ALIAS> FROM table; • Retorna um dict com o valor da expressão
  25. Criando uma classe de QuerySet customizada, podemos criar métodos especiais

    para fazer consultas que podem ser reaproveitadas em diversos lugares do código.