[pyar] Python - Django - select_related

fisa fisadev en gmail.com
Lun Mayo 30 15:43:59 ART 2016


Eso! Por lo general es bastante peligroso concatenar input de usuario con
SQL, hay que usar parameters.

On Mon, May 30, 2016 at 2:57 PM Leonardo Lazzaro <lazzaroleonardo en gmail.com>
wrote:

> Hola,
>
> cuidado que en esa query tenes un problema de seguridad.
> en la doc de django te explican como evitarlo
> https://docs.djangoproject.com/es/1.9/topics/db/sql/
>
> Saludos,
> Leonardo
>
> El 30 de mayo de 2016, 10:46, Jose Luis <joseluiszanotti en gmail.com>
> escribió:
>
>> Actualización...
>>
>> usando este RAW bajo de 1,9 segundos a 170ms la respuesta :D
>>
>> @staticmethod
>> def get_context_data(self, request):
>>     product_info = []
>>     category_id = request.GET['category_id']
>>     main_products = ProductMain.objects.raw(
>>         'SELECT A.id, A.name, A.model, A.status, D.price, D.stock from
>> products_productmain A '
>>         'INNER JOIN products_product B on A.id = B.product_main_id '
>>         'INNER JOIN ( SELECT product_id, MAX(id) as var_id FROM
>> products_productvariation GROUP BY product_id ) as C '
>>         'on B.id = C.product_id '
>>         'INNER JOIN products_productvariation D on D.id = C.var_id '
>>         'WHERE A.main_category_id = ' + category_id
>>     )
>>     for main_product in main_products:
>>         product_info.append({
>>             'status': main_product.status,
>>             'id': main_product.id,
>>             'name': main_product.name,
>>             'model': main_product.model,
>>             'stock': main_product.stock,
>>             'price': main_product.price,
>>             'ml_category_id': main_product.ml_category_id,
>>         })
>>     return product_info
>>
>>
>>
>>
>> El 30/05/16 a las 02:20, fisa escribió:
>>
>> Detalle interesante: veo que usas mucho .values() en las queries. Lo
>> estás haciendo como optimización?
>> Haciendo eso obtenés dicts en lugar de instancias de los modelos, los
>> dicts son un poco más "ásperos", las instancias son bastante más manejables.
>> Si lo que querés es justamente evitar que se creen instancias por temas
>> de performance (te estás trayendo miles de cosas, etc), tiene sentido usar
>> values. Pero si no hay un problema de performance, no veo por qué hacerlo,
>> siendo que hace todo el resto del código un poco más feo.
>> Si no querés traerte toooodos los campos, igual podés traerte instancias
>> del modelo solo queryando (?) los campos que te interesan mediante el uso
>> de only(). (Modelo.objects.filter(blablabla).only('campo1_que_quiero',
>> 'campo2...') )
>>
>> On Sun, May 29, 2016 at 10:35 PM Jose Luis < <joseluiszanotti en gmail.com>
>> joseluiszanotti en gmail.com> wrote:
>>
>>> :/
>>>
>>> El 29/05/16 a las 22:31, fisa escribió:
>>>
>>> My bad! Pensé que main_product era una instancia de ProductMain, pero
>>> mirando veo que no, es un dict que sale de esa query con values antes.
>>> Eso que te dije es para cuando lo que tengas sean instancias de los
>>> modelos, mi error :)
>>>
>>> Saludos!
>>>
>>> On Sun, May 29, 2016 at 10:16 PM Jose Luis <joseluiszanotti en gmail.com>
>>> wrote:
>>>
>>>> Fisa, estuve intentando lo que decis de no usar el ID, pero me tira
>>>> este error "TypeError: int() argument must be a string or a number, not
>>>> 'dict'"
>>>>
>>>> en que parte decis q use
>>>> Product.objects.values('id').get(product_main=main_product) ? dentro del
>>>> loop?
>>>>
>>>> Abrazo
>>>>
>>>>
>>>>
>>>> El 29/05/16 a las 21:33, fisa escribió:
>>>>
>>>> Dos detalles que noto:
>>>>
>>>> 1) No hace falta que uses los _id a mano para comparar, de hecho no es
>>>> recomendable que lo hagas. Podés hacer directamente esto:
>>>> Product.objects.values('id').get(product_main=main_product)
>>>>
>>>> 2) Veo que Por cada ProductMain hay un solo Product, y que no todos los
>>>> Product tienen ProductMain, pero siempre por cada ProductMain asumís que
>>>> existe ese único Product apuntando a él. Qué es lo que te llevó a poner la
>>>> foreign key en Product y no al revés? me suena a que si todo ProductMain
>>>> tiene un único Product asociado, y no a la inversa, entonces es una foreign
>>>> key que va en ProductMain, no? Hacerlo de esa forma además te
>>>> ahorraría/simplificaría un poco las queries (podrías hacer directamente
>>>> ProductMain.filter(...).select_related(relacion_a_product) y te traerías
>>>> todos los ProductMain con sus Product en una sola query re simple).
>>>>
>>>> Saludos!
>>>>
>>>>
>>>>
>>>> On Sun, May 29, 2016 at 9:13 PM Jose Luis <joseluiszanotti en gmail.com>
>>>> wrote:
>>>>
>>>>> Excelente voy a probar en un rato algo parecido a eso.
>>>>>
>>>>> Lo que necesito es obtener es un dict con TODOS los ProductMain + el
>>>>> ultimo valor de ProductVariation de cada ProductMain . Uno de los problemas
>>>>> es que tengo tres tablas.
>>>>>
>>>>> para obtener el ProductVariation necesito consultar el ID en Product,
>>>>> lindo lio hice con las tablas me parece :D
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> El 29/05/16 a las 20:41, Alessandro Odetti escribió:
>>>>>
>>>>> Hola José Luis,
>>>>>
>>>>> si lo que querés efectivamente es obtener los ProductVariation de una
>>>>> categoria de ProductMain, yo lo haría de la siguente forma utlilizando los
>>>>> lookups de Django, quizás alguno te pueda dar una mejor opción:
>>>>>
>>>>> category_id = request.GET['category_id']
>>>>> ProductVariation.objects.values('stock',
>>>>> 'price').filter(product__product_main__main_category_id=category_id)
>>>>>
>>>>> eso te va a dar todos los ProductVariation. Si luego queres obtener el
>>>>> ultimo de cada producto deberias hacer un distinct o algo por el estilo...
>>>>>
>>>>> Espero te sirva. Saludos!
>>>>>
>>>>>
>>>>>
>>>>> El 29 de mayo de 2016, 19:08, Jose Luis < <joseluiszanotti en gmail.com>
>>>>> joseluiszanotti en gmail.com> escribió:
>>>>>
>>>>>> Hola estimados, estoy jugando desde hace una semana con Django, y
>>>>>> estoy migrando una app q tenía en flask a django.
>>>>>>
>>>>>> Mientras voy escribiendo el nuevo código veo la cantidad de cosas
>>>>>> "fuleras" que he escrito hace solo un par de meses, así que aprovecho para
>>>>>> optimizar un poco el código y los tiempos de ejecución.
>>>>>>
>>>>>> Entre las partes de optimización, estoy viendo de o modificar la
>>>>>> estructura de los modelos/tablas o que alguien me oriente a usar
>>>>>> select_related o algun tipo de join. El problema reside en esta parte del
>>>>>> código.
>>>>>>
>>>>>> MODELOS
>>>>>> class ProductMain(models.Model):
>>>>>>     name = models.CharField(max_length=255)
>>>>>>     model = models.CharField(max_length=30)
>>>>>>     description = models.TextField()
>>>>>>     specs = models.TextField()
>>>>>>     update_by = models.DateField(auto_now_add=True)
>>>>>>     status = models.BooleanField()
>>>>>>     image = models.BooleanField()
>>>>>>     main_category = models.ForeignKey('categories.MainCategory')
>>>>>>
>>>>>> class Product(models.Model):
>>>>>>     code = models.CharField(max_length=30)
>>>>>>     name = models.CharField(max_length=255)
>>>>>>     model = models.CharField(max_length=25)
>>>>>>     description = models.TextField(null=True)
>>>>>>     warranty = models.IntegerField()
>>>>>>     tax = models.IntegerField()
>>>>>>     sales = models.IntegerField()
>>>>>>     value = models.DecimalField(max_digits=9, decimal_places=2)
>>>>>>     update_by = models.DateField(auto_now_add=True)
>>>>>>     status = models.BooleanField(default=True)
>>>>>>     product_related = models.ForeignKey(ProductRelated, default=None)
>>>>>>     product_category = models.ForeignKey(ProductCategory,
>>>>>> default=None)
>>>>>>     manufacturer = models.ForeignKey('manufacturers.Manufacturer',
>>>>>> default=None)
>>>>>>     supplier = models.ForeignKey('suppliers.Supplier', default=None)
>>>>>>     product_main = models.ForeignKey(ProductMain, default=None)
>>>>>>
>>>>>>
>>>>>> class ProductVariation(models.Model):
>>>>>>     price = models.DecimalField(max_digits=9, decimal_places=2)
>>>>>>     stock = models.IntegerField()
>>>>>>     incoming = models.IntegerField()
>>>>>>     update_by = models.DateField(auto_now_add=True)
>>>>>>     # status = models.BooleanField(default=True)
>>>>>>     product = models.ForeignKey(Product)
>>>>>>
>>>>>>
>>>>>>
>>>>>> class GetProducts(View):
>>>>>>     def get(self, request):
>>>>>>         return JsonResponse(self.get_context_data(self, request),
>>>>>> safe=False)
>>>>>>
>>>>>>     @staticmethod
>>>>>>     def get_context_data(self, request):
>>>>>>         product_info = []
>>>>>>         category_id = request.GET['category_id']
>>>>>>         main_products =
>>>>>> list(ProductMain.objects.values().filter(main_category_id=category_id))
>>>>>>         # test_products =
>>>>>> list(ProductMain.objects.select_related(Product).filter(main_category_id=category_id))
>>>>>>         # print test_products
>>>>>>         # quit()
>>>>>>         for main_product in main_products:
>>>>>>             product =
>>>>>> Product.objects.values('id').get(product_main_id=main_product['id'])
>>>>>>             stock_price = ProductVariation.objects.values('stock',
>>>>>> 'price').filter(product_id=product['id']).last()
>>>>>>             product_info.append(dict(main_product, **stock_price))
>>>>>>         return product_info
>>>>>>
>>>>>> como verán hace 3 query por separados para obtener los datos stock y
>>>>>> price que estan en otra tabla :/
>>>>>>
>>>>>> Pueden ver la posibilidad de darme una mano (para hacer el query en
>>>>>> una sola linea o para modificar/estructurar los modelos de otra forma),
>>>>>> estoy medio perdido.
>>>>>>
>>>>>> Gracias de antemano!
>>>>>> Sam
>>>>>>
>>>>>> _______________________________________________
>>>>>> pyar mailing list <pyar en python.org.ar>pyar en python.org.ar
>>>>>> http://listas.python.org.ar/listinfo/pyar
>>>>>>
>>>>>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>>>>>
>>>>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre
>>>>>> de Argentina - <http://www.usla.org.ar>http://www.usla.org.ar
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> *- Alessandro Odetti -*
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> pyar mailing list pyar en python.org.arhttp://listas.python.org.ar/listinfo/pyar
>>>>>
>>>>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>>>>
>>>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> pyar mailing list pyar en python.org.ar
>>>>> http://listas.python.org.ar/listinfo/pyar
>>>>>
>>>>> PyAr - Python Argentina - Sitio web: <http://www.python.org.ar/>
>>>>> http://www.python.org.ar/
>>>>>
>>>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>>>>> Argentina - <http://www.usla.org.ar>http://www.usla.org.ar
>>>>
>>>> --
>>>> --
>>>> fisa  -  Juan Pedro Fisanotti
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> pyar mailing list pyar en python.org.arhttp://listas.python.org.ar/listinfo/pyar
>>>>
>>>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>>>
>>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar
>>>>
>>>> _______________________________________________
>>>> pyar mailing list pyar en python.org.ar
>>>> http://listas.python.org.ar/listinfo/pyar
>>>>
>>>> PyAr - Python Argentina - Sitio web: <http://www.python.org.ar/>
>>>> http://www.python.org.ar/
>>>>
>>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>>>> Argentina - <http://www.usla.org.ar>http://www.usla.org.ar
>>>
>>> --
>>> --
>>> fisa  -  Juan Pedro Fisanotti
>>>
>>>
>>> _______________________________________________
>>> pyar mailing list pyar en python.org.arhttp://listas.python.org.ar/listinfo/pyar
>>>
>>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>>
>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar
>>>
>>>
>>> _______________________________________________
>>> pyar mailing list pyar en python.org.ar
>>> http://listas.python.org.ar/listinfo/pyar
>>>
>>> PyAr - Python Argentina - Sitio web: <http://www.python.org.ar/>
>>> http://www.python.org.ar/
>>>
>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>>> Argentina - http://www.usla.org.ar
>>
>> --
>> --
>> fisa  -  Juan Pedro Fisanotti
>>
>>
>> _______________________________________________
>> pyar mailing list pyar en python.org.arhttp://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar
>>
>>
>>
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>> Argentina - http://www.usla.org.ar
>>
>
>
>
> --
> gpg/pgp key: 0x45e1ecde06521134
> <http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x45e1ecde06521134>
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar

-- 
--
fisa  -  Juan Pedro Fisanotti
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20160530/8cbaeea9/attachment-0001.html>


Más información sobre la lista de distribución pyar