更改Django queryset的结构

时间:2016-03-12 16:12:30

标签: python django django-models django-templates

我有几个从父模型继承的模型。

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)

我正在使用Django Model Utils中的InheritanceManager来获取返回子模型的帮助,而不是父模型。

内容对象属于行,列和可选的一组内容对象。

当我使用ContentItem.objects.filter(row__page=page).select_subclasses()查询ContentItem时,我得到类似[<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 class="content-item"> div,这样我就可以直观地将属于同一组的内容项绑定在一起。

1 个答案:

答案 0 :(得分: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)

现在我可以使用嵌套的for循环遍历模板中的行,列和组。