Как создать перекрестный SQL-запрос с помощью Django ORM? - PullRequest
3 голосов
/ 07 декабря 2009

Как использовать Django 1.1, как создать SQL-запрос кросс-таблицы (сводной таблицы) с помощью ORM?

ОБНОВЛЕНИЕ: Это модели и требования к продукции:

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

class Order(models.Model):
    store = models.ForeignKey(Store, blank=True, null=True, related_name='orders')
    description = models.CharField(_('Description'), max_length=255)
    quantity = models.IntegerField(blank=True, null=True)       
    type_detail = models.CharField(_('Type Detail'), max_length=255)
    slug = models.SlugField(blank=True)
    cost = models.DecimalField(_("Cost"), max_digits=14, decimal_places=2)
    modified = models.DateTimeField(_('modified'), auto_now=True)

В настоящее время представление показывает данные примерно так:

Store   | Type Detail  | Quantity 
----------------------------------
Walmart | Floor polish | 2        
Walmart | Tiles        | 1        
Walmart | Milk         | 4      
Another | Floor polish | 2        
Another | Tiles        | 1        
Another | Milk         | 4        

Я хочу повернуть это, чтобы просмотреть данные так:

Для магазина мне нужно знать количество

Store   | Floor polish  | Tiles | Milk
------------------------------------------------
Walmart | 2             | 1     | 4
Another | 2             | 1     | 4

Надеюсь, это объясняет, что мне нужно.

Ответы [ 3 ]

3 голосов
/ 07 декабря 2009

Вы можете сделать это в шаблоне следующим образом (при условии, что вы передаете line_items в свой шаблон, а также при условии, что store.name является уникальным свойством):

{% regroup line_items by store.name as store_items %}
{% for store in store_items %}    
  <tr>
    <td>{{ store.grouper }}</td>
    {% for item in store.list %}
      <td>{{ item.count }}</td>
    {% endfor %}
  </tr>
{% endfor %}

Это будет работать, если все магазины имеют одинаковый инвентарь, в противном случае вам нужно будет заполнить пробелы в представлении (например, возвращая 0 для отсутствующих предметов инвентаря)

2 голосов
/ 21 сентября 2013

Для правильной кросс-таблицы требуется значение для каждого элемента измерения. Вот кое-что, что я сделал (см. Ниже). Вы можете использовать это в шаблоне Django, как в примере с doctext. Таким образом, вы будете выдавать запросы на 1) все значения магазина, 2) все значения type_detail и 3) количество на магазин и type_detail. Результат третьего запроса затем в словарь (магазин, тип) => количество.

class Cube(object):
    """Iterable sparse cube. Iterating gives an item for every dimension member.

    >>> pythons = ['eric', 'john', 'terry']
    >>> cheeses = ['limburg', 'feta', 'parmigiano']
    >>> cheese_consumption = {
        ('eric', 'limburg'): 2,
        ('eric', 'parmigiano'): 4,
        ('john', 'feta'): 5
    }
    >>> cheese_cube = Cube((pythons, cheeses), cheese_consumption)
    >>> for python, python_cheeses in cheese_cube:
        for cheese, consumption in python_cheeses:
            print python, cheese, consumption or 0

    eric limburg 2
    eric feta 0
    eric parmigiano 4
    john limburg 0
    john feta 5 
    john parmigiano 0
    terry limburg 0
    terry feta 0
    terry parmigiano 0
    """
    def __init__(self, dimensions, facts, slice=None):
        self.dimensions = dimensions
        self.data_dict = facts
        self.slice = slice or ()
    def __iter__(self):
        if len(self.slice) + 1 < len(self.dimensions):
            for item in self.dimensions[len(self.slice)]:
                yield item, Cube(self.dimensions, self.data_dict, self.slice + (item,))
        else:
            for item in self.dimensions[len(self.slice)]:
                yield item, self.data_dict.get(self.slice + (item,), None)
0 голосов
/ 11 декабря 2009

Не знаю о Django, но вот простой SQL

SELECT Store,
SUM(CASE WHEN Type_Detail = 'Floor polish' THEN Quantity ELSE 0 END) as 'Floor polish',
SUM(CASE WHEN Type_Detail = 'Tiles' THEN Quantity ELSE 0 END) as 'Tiles',
SUM(CASE WHEN Type_Detail = 'Milk' THEN Quantity ELSE 0 END) as 'Milk'
FROM Order
GROUP BY Store
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...