-
-
Save brunofvpp/cfdae45c897847a7d409 to your computer and use it in GitHub Desktop.
Orm Django
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Django ORM - Melhores práticas | |
Criando sua base de dados | |
Criando seu modelo( Vale para qualquer base de dados do universo, Sql ou não) | |
1. Tente usar poucos joins. Não existe problema se um campo nem sempre for | |
preenchido, campos podem ser nulos por isso mesmo. | |
2. Joins somente em tabelas tipificadoras, que tem poucas linhas (Status, tipo,etc) | |
3. Crie tabelas agrupadoras. Não tem jeito: Varrer todos os dados a procura de | |
quantidades não é bom: Crie tabelas agrupadoras, que guardam totais diários ou | |
mensais ou por objeto, vai depender da sua necessidade | |
3. Pense na força de sua entendade. | |
3.1 Não crie uma tabela de telefones, um ou dois campos é o suficiente. | |
3.2 Não crie uma tabela pra tags. Vai ficar lento, muito lento, e tag é | |
realmente uma entidade?É só um texticulo, use full text search ( | |
http://www.pui.ch/phred/archives/2005/05/tags-with-mysql-fulltext.html ) ou | |
lucene ou... | |
No django | |
Selecionando campos | |
1. Use o select_related com o nome do modelo: Topicos.objects.select_related('Topicos') faz o django tentar fazer um | |
select só dos campos de tópico, sem carregar os comentarios dos tópicos( não usa o join) | |
2. Use values com agrupamentos: Topico.objects.values("titulo").annotate(ultimo_comentario=Max("comentario__id")) | |
Se usar o Max, Count, Avg ou outros agrupamentos com o django, é melhor usar | |
o values, fica bem mais fácil para o django agrupar | |
Filtros | |
1. Tente usar in em vez de Join em filtragens: Topico.objects.filter(campo__in= [1,2,3]) | |
2. Carrega relacionados que participam de uma filtragem antes: | |
editorias = Editoria.objects.filter(name_startswidth='\'); | |
Topico.objects.filter(editoria__id__in= list(editorias)) | |
Django Api | |
1. Querysetizando | |
Classe.objects.filter(id=12)... # filtragem | |
exclude(id=13) #o contrário de filter, cuidado, pode gerar um subselect | |
annotate(Count('Entry')) # usado em agrupadores | |
order_by('-id') # ordenação, use - na frente para ordenar decrescetemente, | |
reverse() # inverte o retorno | |
distinct() # elimina duplicatas | |
values('id', 'nome') # retorna uma lista de dicts [{'id':1, 'nome':'João'}, {'id':2, nome:'Rita'}] | |
values_list('id', 'nome')# retorna uma lista de tuplas [(1, 'João'), (2,'Rita')] | |
dates('data_criacao', 'year') # retorna uma lista de datetime objects, truncado para | |
ano mes ou dia:[datetime.datetime(2005, 1, 1)] | |
none() # retorna um queryset vazio | |
all() # retorna todos os objetos do queryset. Não use | |
select_related() # carrega o maximo de relacionamentos na mesma query. Pode | |
ser bom ou ruim | |
select_related('Topico') # limita as classes que são retornadas no mesmo select. | |
select_related(depth=1) # limita o select related somente ao primeiro nivel. | |
escolha seu nivel | |
prefetch_related() #em dev, pré carrega em memória os objetos relacionados | |
extra(select={'is_recent': "pub_date > '2006-01-01'", param_test:'%s'}, | |
where=['id IN (3, 4, 5, 20)', 'headline=%s'], | |
params=['Lennon'], | |
tables=None, order_by=['-is_recent'], | |
select_params=['test']) # adiciona campos, wheres... | |
defer('campo_blob_com_imagem') #não carrega estes campos, otimo para blobs | |
only('campos','leves') #só carrega estes campos, inverso de only | |
using('database_name') # escolhe a base de dados em que deve ser feito o queryset | |
select_for_update().filter... #em dev, oracle, mysql, postgres | |
suportam. Seleciona todos os registros para update, liberando após o commit | |
2. Metodos que não retornam querysets | |
get(pk=1) # retorna um único objeto | |
create(nome='rá', data_criacao=datetime.now) # cria um objeto. dãããããã | |
bulk_create([Entry(headline='django'), Entry(headline='rá')] # cria um monte de objetos de uma vez | |
get_or_create(nome='django', idade=1) # pega o objeto na base de dados ou cria | |
count() # retorna a contagem de objetos no db. Cuidado, pode ser custoso | |
in_bulk([1,2,3]) # retorna uma lista de objetos pelo o conjunto de ids | |
iterator() # retorna um iterator, para ser usado em um loop. Não use. | |
latest(). # retorna o ultimo objeto | |
aggregate(number_of_entries=Count('entry')) # retorna um agregado usando as | |
funções agregacionais | |
exists() # retorna true se o resultado do queryset é diferente de null | |
update(nome=2010) # atualiza em lote : Class.objects.filter(a=2).update(nome='Valdemar') | |
delete() # deleta em lote : Classe.objects.filter(a=1).delete() | |
2. Operadores Djangonicos(use em filter, exclude...): | |
campo__exact # valor exato | |
campo__notnull=True , | |
campo_data__range=(datainicial, datafinal), | |
campo__gt=valor #maior que | |
campo__gte=valor #maior ou igual | |
campo__lt=valor #menor | |
campo__lte=valor #menor ou igual | |
campo__startswith='Will' #like 'Will%' | |
campo__istartswith='Will' #ilike 'Will%' , case insensitive | |
campo__endswidth='cats' #like '%cats' | |
campo__iendswidth='cats' #ilike 'cats%' | |
campo__month=12 #para campos datas, filtra pelo mes | |
campo__year=2019 | |
campo__day=3 | |
campo__weekday=7 | |
campo__search='+Jazz -python' #full text search, db depedent | |
campo__regex=r'^(An?|The) +' #regex | |
campo__iregex=r'^(An?|The) +' #regex case insensitive | |
3. Agrupadores Djangonicos | |
Avg, Count, Max, Min, StdDev, Sum, Variance(field, sample=False) | |
Use em annotate, filter, exclude |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment