[pyar] Python - Django - select_related

Jose Luis joseluiszanotti en gmail.com
Dom Mayo 29 19:08:32 ART 2016


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



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