[pyar] Python - Django - select_related

Leonardo Lazzaro lazzaroleonardo en gmail.com
Lun Mayo 30 14:57:04 ART 2016


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


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