ModelViewSet Queryset Фильтр со значением на основе таблицы с другой таблицей
В моей базе данных есть две таблицы ProductStock
и Sales
. Я храню информацию о продукте в таблице ProductStock
, а информацию о продажах в таблице Sales
На основе общей суммы проданного количества я хочу отфильтровать данные и вернуть только те данные, количество которых больше 0.
например,
ДАННЫЕ О ЗАПАСАХ ПРОДУКЦИИ
ID | PRODUCT | QUANTITY |
---|---|---|
1 | Django Course | 50 |
2 | Social Codia | 50 |
ДАННЫЕ О ПРОДАЖАХ
PRODUCT_STOCK_ID | QUANTITY |
---|---|
1 | 5 |
1 | 45 |
2 | 35 |
2 | 10 |
Здесь проданное количество продукта 1 составляет 5+45=50
, что означает, что для продукта 1 в базе данных не осталось запасов.
ВОПРОС В КОРОТКОМ СМЫСЛЕ : Как я могу получить все эти продукты, количество которых больше current_quantity - sold_quantity
больше 0.
Моя модель склада
class ProductStock(Core):
medical = models.ForeignKey(Medical, on_delete=models.CASCADE)
distributer = models.ForeignKey(Distributer,on_delete=models.DO_NOTHING)
product = models.ForeignKey(Product,on_delete=models.CASCADE,related_name='product')
variant = models.ForeignKey(Attribute,on_delete=models.DO_NOTHING)
batch = models.CharField(max_length=20,null=True, blank=True)
purchase_price = models.CharField(max_length=10,null=False, blank=False)
price = models.CharField(max_length=10,null=False,blank=False)
quantity = models.IntegerField(null=False,blank=False)
location = models.ForeignKey(Location, on_delete=models.DO_NOTHING)
low_stock = models.IntegerField(default=10,null=False,blank=False)
expire_date = models.DateTimeField(null=False,blank=False)
Моя Модель ПРОДАЖ
class Sale(Core):
product_stock = models.ForeignKey(ProductStock,on_delete=models.CASCADE,related_name='sales')
medical = models.ForeignKey(Medical,on_delete=models.CASCADE,related_name='medical')
quantity = models.IntegerField(default=1,null=False,blank=False)
price = models.CharField(max_length=10,null=False,blank=False)
discount = models.FloatField(max_length=10,default=0)
ProductStockViewSet
class ProductStockViewSet(ModelViewSet):
serializer_class = ProductStockSerializer
permission_classes = [IsAuthenticated]
authentication_classes = [JWTAuthentication]
def get_queryset(self):
return ProductStock.objects.all()
Для решения проблемы я переопределил list
из ProductStockViewSet
, используя цикл for, получающий общее количество проданных товаров, и, подставляя в него фактическое количество, я получаю текущее количество.
Но я знаю, что это не может быть хорошим решением для получения таких данных.
def list(self,request,pk=None):
products = ProductStock.objects.all()
for product in products:
quantities = Sale.objects.filter(product_stock=product).aggregate(quantities = Sum('quantity')).get('quantities')
if quantities is not None:
current_quantity = product.quantity - quantities
print(f'QUANTITY : {product.quantity} ==== SOLD QUANTITY : {quantities} ==== CURRENT QUANTITY : {current_quantity}' ,)
product.quantity = current_quantity
serializer = ProductStockSerializer(products,many=True)
return Response(serializer.data)
Любые предложения будут приняты с благодарностью.
Спасибо
запрос, который вы хотели:
from django.db.models import F, Sum
ProductStock.objects.alias(
quantity_sold=Sum('sales__quantity')
).filter(
quantity_sold__lt=F('quantity')
)
* Значением по умолчанию для null и blank параметров полей является False, поэтому нет необходимости передавать null=False, blank=False
каждому созданному вами полю.