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 каждому созданному вами полю.

Вернуться на верх