Как да комбинирате 2 различни модела с „Модел в средата“?

Създавам HTML таблица, която ще показва наличните наличности от списък с продукти в различни складове. Но продуктът (разбира се) не е директно обвързан със склад. Това е подвързано с трети модел. Идеята е, че създавам таблицата и в най-лявата колона ще имате списък с продукти, с вертикални колони със складовата наличност.

Проблемът идва, когато не всички складове могат да разполагат с този продукт. Така че те няма да се появят в базата данни. Пример: Продукт X никога няма да отиде в склад A, така че записът за наличност с тези съответно няма да бъде създаден.

Вече опитах успешно нещо и работи, но имам чувството, че кодът е наистина лош. Определено, тъй като Django Templates трябва да бъдат възможно най-лесни. Това не е:

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

class Warehouse(models.Model):
    name = models.CharField(....

class Stock(models.Model):
    product = models.ForeignKey(Product...
    warehouse = models.ForeignKey(Warehouse...
    quantity = models.CharField(....

@register.simple_tag # I'll get to this
def get_k_v(l, key, v):
    try:
        return l.get(**{key: v})
    except:
        return None

Това, което правя сега, е, че преминавам през продуктите и вътре във всеки ред преминавам през всички складове, използвайки обратно извикване към функция, ако съществува, показвам количеството, ако не, клетката ще стане сива (засега може промяна).

Визуализация:

{% for product in products %}
    <tr>
         <td>{{ product }}</td>
         {% for warehouse in warehouses %}
              {% get_k_v product.stock_set 'warehouse' warehouse as ware_prod %}
              {% if ware_prod %} ...

Както можете да си представите и вероятно да се съгласите с мен, въпреки че това работи, изглежда зле и бих казал, че е наистина лошо представяне. Имаме 300+ продукта в база данни и зареждането с 10 склада вече отнема няколко секунди.

Тъй като не съм толкова напреднал (все още) с Django, се чудя как мога да подобря това.

РЕДАКТИРАНЕ: Опитвах се да реша това и създадох заявка, която извежда искания резултат. Изглежда така:

SELECT products.id, products.name, warehouses.id, warehouses.name, stock.quantity
FROM products CROSS JOIN warehouses
LEFT JOIN stock ON stock.product_id = products.id AND stock.warehouse_id = warehouses.id

Има ли начин да се приложи това с помощта на ORM на Django? Или като алтернативна заявка, която дава същия или много подобен резултат?


person MrDikke    schedule 11.05.2019    source източник


Отговори (1)


Можете да използвате необработен SQL:

from django.db import connection
query='SELECT app_product.id, app_product.name, app_warehouse.id, app_warehouse.name, app_stock.quantity \
       FROM app_product CROSS JOIN app_warehouse \
       LEFT JOIN app_stock ON app_stock.product_id = app_product.id AND app_stock.warehouse_id = app_warehouse.id'
with connection.cursor() as cursor:
   cursor.execute(query)
   result_table = cursor.fetchall()

Повече информация за необработения SQL има тук: https://docs.djangoproject.com/en/2.2/topics/db/sql/#executing-custom-sql-directly

person Slava    schedule 17.05.2019