2016-03-12 4 views
1

У меня есть пара моделей, которые наследуются от родительской модели.Изменить структуру Django queryset

class ContentItem(models.Model): 

    COLUMN_CHOICES = (
     (FIRST_COLUMN, 1), 
     (SECOND_COLUMN, 2), 
     (THIRD_COLUMN, 3), 
    ) 

    row  = models.ForeignKey(RowItem) 
    column = models.SmallIntegerField(choices=COLUMN_CHOICES, default=FIRST_COLUMN) 
    group = models.IntegerField(default=0, unique=False, null=False, blank=False) 

    objects = InheritanceManager() 


class TextItem(ContentItem): 

    title = models.CharField(max_length=500, unique=False, null=True, blank=True) 
    content = models.TextField(max_length=50000, unique=False, null=True, blank=True) 

class FaqItem(ContentItem): 

    question = models.TextField(max_length=1000, unique=False, null=True, blank=True) 
    answer = models.TextField(max_length=5000, unique=False, null=True, blank=True) 

Я использую InheritanceManager из Django Model Utils помощи с возвратом модель ребенка, а не родителя.

Объекты контента относятся к строке, столбцу и, необязательно, группе объектов контента.

Когда я запрашиваю ContentItems с ContentItem.objects.filter(row__page=page).select_subclasses(), я получаю что-то вроде этого [<FaqItem: FaqItem object>, <FaqItem: FaqItem object>, <TextItem: TextItem object>].

До сих пор я могу получить данные в его структуре, но я ударил стену и не смог достичь желаемого сложного HTML-макета в шаблоне, в частности, с дополнительной группировкой объектов по полю группы.

Я думаю, что наличие данных во вложенной структуре упростит цикл и создаст желаемую структуру шаблона строк, содержащих столбцы, содержащие элементы контента, некоторые из которых сгруппированы, некоторые из которых автономны. т.е. такая интерпретация:

content_items { 
    'rows': { 
     0: { 
      'columns': { 
       0: { 
        'faq_items': { 
         'groups': { 
          0: { 
           faq_obj, 
           faq_obj, 
          }, 
          1: { 
           faq_obj, 
           faq_obj, 
           faq_obj, 
          }, 
         }, 
         faq_obj, 
        'text_items': { 
         'groups': { 
          0: { 
           text_obj, 
           text_obj, 
          }, 
         }, 
         text_obj, 
         text_obj, 
         text_obj, 
        } 
       1: ... 
      }, 
     }, 
     1: ... 
    } 
} 

Возможно ли это? Или есть способ, которым я могу это сделать в шаблоне. В настоящее время он выглядит следующим образом:

{% for content_item in content_items %} 
    {% if content_item.row == row and content_item.column == column_number %} 
     <div class="content-item"> 
      {% include "content-item.html" %} 
     </div> 
    {% endif %} 
{% endfor %} 

«row» и «column_number» передаются в этот шаблон. Это работает нормально. Но когда элементы контента находятся в одной группе, я хочу обойти div <div class="content-item">, чтобы я мог визуально связать элементы контента, принадлежащие одной группе.

ответ

1

Этот ответ показал, что я создал вложенный объект из набора запросов, группируя более чем одно поле модели - Nested GROUP BY in django: returning Objects. Я пришел с этим:

content_items  = ContentItem.objects.filter(row__page=page).select_subclasses() 
content_items_sorted = {} 

for row, first_group in groupby(content_items, lambda x: x.row): 
    content_items_sorted[row] = {} 
    for column, second_group in groupby(first_group, lambda x: x.column): 
     content_items_sorted[row][column] = {} 
     for group, third_group in groupby(second_group, lambda x: x.group): 
      content_items_sorted[row][column][group] = list(third_group) 

Теперь я могу Переберите строки, столбцы и группы в шаблоне с использованием вложенным для петель.