[pyar] Python - Django - select_related

Jose Luis joseluiszanotti en gmail.com
Lun Mayo 30 07:01:39 ART 2016


Nuevamente gracias FIsa, como bien decís uso el values() para optimizar 
un poco, es algo más rápido. Lo de la perfomance me interesa por que con 
ese/esos queries envío los datos (json) al frontend, y pienso q es 
importante que el usuario (yo) tenga los datos lo antes posible. Me 
parece q 1-2 segundos hace la diferencia en la experiencia de uso de la app

Voy a probar lo de usar instancias a ver q onda... creo la instancia y 
luego un dict para enviarlo al frontend.





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 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/dbb15d73/attachment-0001.html>


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