Skip to content

Instantly share code, notes, and snippets.

@brunofvpp
Forked from tarsisazevedo/orm_django.txt
Created January 2, 2016 23:25
Show Gist options
  • Save brunofvpp/cfdae45c897847a7d409 to your computer and use it in GitHub Desktop.
Save brunofvpp/cfdae45c897847a7d409 to your computer and use it in GitHub Desktop.
Orm Django
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