Запрос нескольких внешних ключей в Django - PullRequest
0 голосов
/ 01 октября 2019

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

Models.py

class Kit(models.Model):
    kit_name = models.CharField(max_length=255, default=0)
    kit_info = models.CharField(max_length=255, default=0)
    components_per_kit = models.IntegerField(default=0)

    product1 = models.ForeignKey(Product,on_delete=models.CASCADE, related_name='kit_product1')
    product1_information = models.CharField(max_length=255, default=0)
    product1_quantity = models.IntegerField(default=0)
    product1_unitprice = models.IntegerField(default=0)

    product2 = models.ForeignKey(Product,on_delete=models.CASCADE, related_name='kit_product2')
    product2_information = models.CharField(max_length=255, default=0)
    product2_quantity = models.IntegerField(default=0)
    product2_unitprice = models.IntegerField(default=0)

    product3 = models.ForeignKey(Product,on_delete=models.CASCADE, related_name='kit_product3')
    product3_information = models.CharField(max_length=255, default=0)
    product3_quantity = models.IntegerField(default=0)
    product3_unitprice = models.IntegerField(default=0)

    product4 = models.ForeignKey(Product,on_delete=models.CASCADE, related_name='kit_product4')
    product4_information = models.CharField(max_length=255, default=0)
    product4_quantity = models.IntegerField(default=0)
    product4_unitprice = models.IntegerField(default=0)

    product5 = models.ForeignKey(Product,on_delete=models.CASCADE, related_name='kit_product5')
    product5_information = models.CharField(max_length=255, default=0)
    product5_quantity = models.IntegerField(default=0)
    product5_unitprice = models.IntegerField(default=0)

    kit_client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='kit_owner')

    def __str__ (self):
        return self.kit_name

class Product(models.Model):
    category = (('Metal', 'Metal'), ('Wood', 'Wood'), ('Plastic', 'Plastic'))
    product_id = models.IntegerField(default=0)
    product_name = models.CharField(max_length=255, default=0)
    product_category = models.CharField(max_length=255, default=0, choices=category)
    product_quantity = models.IntegerField(default=0)
    product_owner = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='product_owner')

и в моем views.py я запрашиваю такие продукты:

def load_product (request):
    kit_id = request.GET.get('kit')
    product1 = Product.objects.filter(kit_product1=kit_id)
    product2 = Product.objects.filter(kit_product2=kit_id)
    product3 = Product.objects.filter(kit_product3=kit_id)
    product4 = Product.objects.filter(kit_product4=kit_id)
    product5 = Product.objects.filter(kit_product5=kit_id)

    products = list(chain(product1, product2, product3,product4,product5))

    print("products are", products)
    return render(request, 'packsapp/employee/kit_product_list_options.html', {'products': products})

Есть ли другой способ получить доступ ко всем продуктам в наборе, потому что эти запросы возвращают следующее:

products are [<Product: 1111::Plastic Pallet>, <Product: 1122::Side wall>, <Product: 1133::Top Lid>, <Product: 1144::Insert>, <Product: 1155::Separator sheets>]

, но я не получаю количество продуктов в конкретномКомплект.

Как запросить все продукты в наборе и их количество?

1 Ответ

0 голосов
/ 01 октября 2019

Вы можете попробовать вот так: Q:

from django.db.models import Q

products = Product.objects.filter(Q(kit_product1=kit_id)|Q(kit_product2=kit_id)|Q(kit_product3=kit_id))

Если вы хотите добавить количество всех продуктов, используйте .count()

print(products.count())

Кроме того, вы можете аннотировать счет для каждого типа продукта набора (используя conditional aggregation):

from django.db.models import Count, Case, IntegerField

qset = products.annotate(kit_product1_count=Count(Case(
    When(kit_product1=kit_id, then=1),
    output_field=IntegerField(),
))).annotate(kit_product2_count=Count(Case(
    When(kit_product2=kit_id, then=1),
    output_field=IntegerField(),
))).annotate(kit_product3_count=Count(Case(
    When(kit_product3=kit_id, then=1),
    output_field=IntegerField(),
)))

# Ways to get the kit count

qset.values('kit_product1_count', 'kit_product2_count', 'kit_product3_count')

for item in qset:
   print(item.kit_product1_count)
   print(item.kit_product2_count)
   ...
...