def mejores(self, producto, ciudad=None, punto_o_sucursal=None, radio=None, dias=None, limite=5): """ devuelve una lista de instancias Precio para el producto, ordenados por menor precio (importe) para un determinado producto y un radio de distancia o ciudad. Sólo considera el último precio en cada sucursal. """ if not one((ciudad, radio)): raise ValueError( 'Debe proveer una ciudad o un radio en kilometros') if one((radio, punto_o_sucursal)): raise ValueError( 'Si se especifica radio debe proveer el punto o sucursal') qs = super(PrecioManager, self).get_queryset().filter(producto=producto, activo__isnull=False) if dias: desde = timezone.now() - timedelta(days=dias) qs = qs.filter(created__gte=desde) if radio: if isinstance(punto_o_sucursal, Sucursal): punto = punto_o_sucursal.ubicacion else: punto = punto_o_sucursal cercanas = Sucursal.objects.filter( ubicacion__distance_lte=(punto, D(km=radio))) cercanas = cercanas.values_list('id', flat=True) qs = qs.filter( sucursal__id__in=cercanas).distinct('sucursal')[:limite] elif ciudad: if isinstance(ciudad, City): ciudad = ciudad.id qs = qs.filter( sucursal__ciudad__id=ciudad).distinct('sucursal')[:limite] if qs.exists(): return sorted(qs, key=lambda i: i.precio) return []
def mejores(self, producto, ciudad=None, punto_o_sucursal=None, radio=None, dias=None, limite=5): """ devuelve una lista de instancias Precio para el producto, ordenados por menor precio (importe) para un determinado producto y un radio de distancia o ciudad. Sólo considera el último precio en cada sucursal. """ if not one((ciudad, radio)): raise ValueError( 'Debe proveer una ciudad o un radio en kilometros') if one((radio, punto_o_sucursal)): raise ValueError( 'Si se especifica radio debe proveer el punto o sucursal') qs = super(PrecioManager, self).get_queryset().filter(producto=producto, activo__isnull=False) if dias: desde = timezone.now() - timedelta(days=dias) qs = qs.filter(created__gte=desde) if radio: if isinstance(punto_o_sucursal, Sucursal): punto = punto_o_sucursal.ubicacion else: punto = punto_o_sucursal cercanas = Sucursal.objects.filter(ubicacion__distance_lte=(punto, D(km=radio))) cercanas = cercanas.values_list('id', flat=True) qs = qs.filter(sucursal__id__in=cercanas).distinct( 'sucursal')[:limite] elif ciudad: if isinstance(ciudad, City): ciudad = ciudad.id qs = qs.filter(sucursal__ciudad__id=ciudad).distinct( 'sucursal')[:limite] if qs.exists(): return sorted(qs, key=lambda i: i.precio) return []
def clean(self): if not any((self.cadena, self.nombre)): raise ValidationError( u'Indique la cadena o el nombre del comercio') if not self.online and not self.direccion: raise ValidationError(u'Una sucursal física debe tener dirección') if self.online and not self.url: raise ValidationError( u'La url es obligatoria para sucursales online') if not one((self.direccion, self.online)): raise ValidationError(u'La sucursal debe ser online ' u'o tener direccion física, pero no ambas') if (self.ubicacion and self.cadena and self.cercanas(radio=0.05, misma_cadena=True).exists()): raise ValidationError( u'Hay una sucursal de la misma cadena a menos de 50 metros')
def clean(self): if not any((self.cadena, self.nombre)): raise ValidationError( u'Indique la cadena o el nombre del comercio') if not self.online and not self.direccion: raise ValidationError( u'Una sucursal física debe tener dirección') if self.online and not self.url: raise ValidationError( u'La url es obligatoria para sucursales online') if not one((self.direccion, self.online)): raise ValidationError(u'La sucursal debe ser online ' u'o tener direccion física, pero no ambas') if (self.ubicacion and self.cadena and self.cercanas(radio=0.05, misma_cadena=True).exists()): raise ValidationError( u'Hay una sucursal de la misma cadena a menos de 50 metros')