Как получить значение атрибута из модели django - PullRequest
1 голос
/ 28 марта 2020

У меня есть список продуктов:

product_list = ['A', 'B', 'C', 'D', 'E', 'F']

, и я хочу узнать общее количество этого продукта, которое есть в моей AllotmentDocket модели

Models.py

class AllotmentDocket(models.Model):

    transaction_no = models.IntegerField(default=0, blank=True, null=True)

    product1 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product1_quantity = models.IntegerField(default=0, blank=True, null=True)

    product2 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product2_quantity = models.IntegerField(default=0, blank=True, null=True)

    product3 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product3_quantity = models.IntegerField(default=0, blank=True, null=True)

    product4 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product4_quantity = models.IntegerField(default=0, blank=True, null=True)

    product5 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product5_quantity = models.IntegerField(default=0, blank=True, null=True)

    product6 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product6_quantity = models.IntegerField(default=0, blank=True, null=True)

    product7 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product7_quantity = models.IntegerField(default=0, blank=True, null=True)

    product8 = models.CharField(max_length=500, default=0, blank=True, null=True)
    product8_quantity = models.IntegerField(default=0, blank=True, null=True)

Как я могу это сделать?

1 Ответ

2 голосов
/ 28 марта 2020

Вы можете сделать это следующим образом:

from django.db.models import F, Sum

allotment_dockets = AllotmentDocket.objects.annotate(total_quantity=F('product1_quantity')+F('product2_quantity')+F('product3_quantity')+F('product4_quantity')+F('product5_quantity')+F('product6_quantity')+F('product7_quantity')+F('product8_quantity'))

print(allotment_dockets.values('total_quantity'))

Если вы хотите получить сумму total_quantity для всех AllotmentDocket, используйте aggregation:

total = allotment_dockets.aggregate(total=Sum('total_quantity'))['total']

print(total)

Для количества продукта

ИМХО, дизайн вашей модели не верный. Ваш продукт должен быть отдельной моделью, и он должен быть подключен к AllotmentDocket через ForeignKey или M2M. В любом случае, я думаю, что вы можете использовать этот подход:

product_list = ['A', 'B', 'C', 'D', 'E', 'F']
product_model_fields = ['product1', 'product2', 'product3', 'product4',...# so on]

total = 0
item_wise_quantity = {}

for product in product_list:
   for field in product_model_fields:
        query = {field:product}
        items = AllotmentDocket.objects.filter(**query)
        for item in items:
            quantity = getattr(item, field+'_quantity')
            total += quantity
            item_wise_quantity[product] = item_wise_quantity.get(product, 0) + quantity

print(item_wise_quantity)

Оптимальный дизайн модели

# model

class AllotmentDocket(models.Model):
    transaction_no = models.IntegerField(default=0, blank=True, null=True)
    product = models.ManyToManyField("Product", through="ProductAllotment")

class Product(models.Model):
    name = models.CharField(max_length=255)

class ProductAllotment(models.Model):
    allotment = models.ForeignKey(AllotmentDocket, on_delete=models.CASCADE, related_name="products")
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="allotments")
    quantity = models.IntegerField(default=0)

# query

product_list = ['A', 'B', 'C', 'D', 'E', 'F']

products = Product.objects.filter(name__in=product_list).annotate(sum_product=Sum('allotments__quantity')
# individual product quantity
products.values('name','sum_product')
# total sum
products.aggregate(sum=Sum('sum_product'))['sum']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...