[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