[pyar] Python - Django - select_related

fisa fisadev en gmail.com
Lun Mayo 30 02:20:30 ART 2016


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>
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>
>>> 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
>>>> 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 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
>>
>> --
>> --
>> 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
>
> --
> --
> 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

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


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