[pyar] Python - Django - select_related

Jose Luis joseluiszanotti en gmail.com
Lun Mayo 30 16:06:48 ART 2016


Perfecto! Muchas gracias!



El 30/05/16 a las 14:57, Leonardo Lazzaro escribió:
> 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 
> <mailto: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 <http://main_product.id>,
>                 'name': main_product.name <http://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 <mailto: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
>>>         <mailto: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
>>>>             <mailto: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
>>>>>                 <mailto: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
>>>>>                     <mailto: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
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>                 -- 
>>>>>                 *- Alessandro Odetti -*
>>>>>
>>>>>
>>>>>                 _______________________________________________
>>>>>                 pyar mailing listpyar en python.org.ar <mailto: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
>>>>
>>>>                 _______________________________________________
>>>>                 pyar mailing list pyar en python.org.ar
>>>>                 <mailto: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
>>>>
>>>>
>>>>             _______________________________________________
>>>>             pyar mailing listpyar en python.org.ar <mailto: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
>>>             _______________________________________________
>>>             pyar mailing list pyar en python.org.ar
>>>             <mailto: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
>>>
>>>
>>>         _______________________________________________
>>>         pyar mailing listpyar en python.org.ar <mailto: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
>>
>>         _______________________________________________
>>         pyar mailing list pyar en python.org.ar <mailto: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
>>
>>
>>     _______________________________________________
>>     pyar mailing listpyar en python.org.ar <mailto: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
>
>
>     _______________________________________________
>     pyar mailing list pyar en python.org.ar <mailto: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

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


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