hacklabr / django-cards

Cards functionality for Django sites
GNU Affero General Public License v3.0
1 stars 3 forks source link

Filtrar por contratos é ridiculamente custoso #6

Closed tiagofassoni closed 7 years ago

tiagofassoni commented 7 years ago

Como contratos é um many-to-many de grupos, para pegar os usuários do mesmo contrato, eu tenho que: 1) pegar todos os grupos do usuário 2) pegar todos os contratos de 1) 3) pegar todos os grupos de 2) 4) pegar todos os usuários de 3) 5) transformar 4) num set() por causa da repetição toda.

Isso demora UM ABSURDO de tempo. Então, antes de implementar isso em código, acho melhor a gente discutir formas alternativas disso.

Sente o tamanho da treta:

set([ eeita for eeita in usuario.user_set.all() 
for usuario in galera.groups.all() 
for galera in g.contracts.all() 
for g in laury.groups.all()])
tiagofassoni commented 7 years ago

Estou invocando aqui @brunosmartin e @laurybueno.

Consigo resolver esse treco fazendo uma materialized view e alguns triggers para dar update toda hora que a tabela paralapraca_contract_groups for alterada.

É feio? Sim. Facilita mega master blaster a vida? Sim

tiagofassoni commented 7 years ago

Conseguido via... uma concatenação bonita de foreign keys.

O que seria a seguinte query:

listao = []
for g in self.request.user.groups.all():
    for contrato in g.contracts.all():
        for galera_do_contrato in contrato.groups.all():
            for usuario in galera_do_contrato.user_set.all():
                listao.append(usuario)

virou

galera = TimtecUser.objects.filter( groups__contracts__groups__in = self.request.user.groups.all() )