[pyar] django Q

Juan BC jbc.develop en gmail.com
Vie Ago 5 17:33:27 ART 2011


El 05/08/11 16:49, Daniel escribió:
> El día 5 de agosto de 2011 11:25, fisa<fisadev en gmail.com>  escribió:
>> 2011/8/5 Daniel<dmlistapython en gmail.com>:
>>> Hola Gente linda:
>>>
>>> teniendo en cuenta este código
>>>
>>> def nuevaQ(valor, filtro="__icontains"):
>>>       campo="titulo"
>>>       rset = Q(campo+filtro=valor) **
>>>
>>> dado que Q no recibe string como nombre del parámetro
>>> ¿cómo puedo hacer para que el campo y el filtro** provengan de una variable?
>>>
>>> Espero que se entienda
>>>
>>> --
>>> Daniel Malisani
>>
>> Buenas! te vuelvo a responder acá, para que le sirva también al resto
>> de la gente.
>>
>> Varias cosas
>>
>> 1) no necesitás usar Q(), lo que querés armar es simple y se puede
>> hacer con filters.
>> 2) varias condiciones en un filter es equivalentes a ands en la query
>> 3) podés "desarmar" un diccionario para pasarlo como parámetros a una
>> función con **
>> 4) podés concatenar filters, y es lo mismo que poner varios campos en
>> un filter, es decir que se arman con ands en la query sql
>
> ¿cómo funciona respecto a la performance? (me da la sensación -sin fundamento-
> que filters encadenados sería más lento
>
>>
>> Con esas cosas:
>>
>> def hacer_filtros(frase, campos):
>>     filtros = dict((c + '__icointains', p)
>>                       for p in frase.split()
>>                       for c in campos)
>>     return Modeloxx.objects.filter(**filtros)
>
> igual debo "atarlo" al modelo que es lo que no quería
>>
>> o si querés pasarle el query set como parámetro:
>>
>> def hacer_filtros(qs, frase, campos):
>>     filtros = dict((c + '__icointains', p)
>>                       for p in frase.split()
>>                       for c in campos)
>>     return qs.filter(**filtros)
>>
>> Otra cosa aparte:
>> En lo que vos hacías hay algo que nunca andaría, que es esto:
>> Q(campo+filtro=valor)
>> Nunca podés hacer ese "campo+valor" en la parte izquierda de un
>> parámetro de algo. La parte izquierda es un nombre, y no "algo que
> eso motivó la consulta
>
> la versión con Qs la tengo "medianamente" resuelta
> http://pastebin.com/689WmdvU
> (solo funciona con AND entre los Q y no se como modificarla para que haga OR
> ¿alguna idea?
>
> voy a tratar de hacerlo también con filtros para tener otra versión

esto deberia andarte igual que lo tuyo pero con dos lineas y 1/4 menos

def definirQ(texto_busqueda, campos, filtro="__icontains"):
     from django.db.models import Q
     from django.utils import   tree
     palabras=texto_busqueda.split()
     rset=None
     for word in palabras:
         for field in campos:
              if rset is None:
                  rset = (Q(**{field+filtro:word}))
              else:
                  rset.add(Q(**{field+filtro:word}), rset.connector)
     return rset





More information about the pyar mailing list