自定义重组订单

时间:2011-08-12 22:25:56

标签: django django-templates django-views

我想使用自定义排序方案对Django模板中的查询集进行重新排序。

这是模板代码:

{% regroup teams_at_school by season.school_year as teams %}
    <ul id="sport-picker">
        <li class="first"><span>Sports by year</span></li>
            {% for team_grouper in teams|dictsort:"season__school_year" %}
            <li><span>{{ team_grouper.grouper }}<img src="http://hometeam.s3.amazonaws.com/graphics/down-pointer.png"></span>
                <ul class="dropper">
                    {% for team_list in team_grouper.list|dictsort:"sport.sport" %}
                    <li><a href="{{ team_list.season.season_start_date.year }}/{{ team_list.sport.sport_slug }}/">{{ team_list.sport }} {% if team_list.total_wins > 0 or team_list.total_losses > 0 %}({{ team_list.total_wins }}-{{ team_list.total_losses }}){% endif %}</a></li>
                    {% endfor %}
                </ul>
            </li>
            {% endfor %}
    </ul>

产生这个输出:

School years with incorrect ordering


如您所见,学年的顺序并不理想。数据以这种方式出现在数据库中:

 id | school_year 
----+-------------
  1 | 2010-2011
  2 | 2009-2010
  3 | 2011-2012

我想按年重新排序结果。在SQL中,这将以这种方式表达:

select * from seasons_schoolyear order by substring(school_year from 1 for 4);

具有以下结果:

 id | school_year 
----+-------------
  2 | 2009-2010
  1 | 2010-2011
  3 | 2011-2012

是否有办法在创建查询集的语句中实现此排序:

teams_at_school = Team.objects.filter(school=team).order_by('season__school_year')

或在模板的regroup声明中?

3 个答案:

答案 0 :(得分:1)

将dictsort添加到您的regroup标记中,如下所示:{% regroup teams_at_school|dictsort:"school_year" by season.school_year as teams %}并删除标记 标记 标记下的团队的dict排序。

答案 1 :(得分:0)

您可以使用额外的查询集来创建您需要订购的值,例如:

Team.objects.filter(school=team).select_related(depth=1)
    extra(select={"first_year":"SUBSTRING(yourmodule_school.year from 1 for 4)"}).
    order_by("-first_year")

yourmodule_school应该是数据库中必须在Team上有外键的表。

您可以使用导入django.db.connection并执行connection.queries来检查查询是否正在执行您所期望的操作,由于select_related(depth = 1),它将执行连接。如果模块上有多个外键,那么在没有一些不必要的连接的情况下执行此操作的另一种方法是在额外字段上执行SELECT查询,如下所示:

Team.objects.filter(school=team).
    extra(select={"first_year":"SELECT SUBSTRING(year from 1 for 4)
    FROM yourmodule_school WHERE id=school_id"}).
    order_by("-first_year")

其中school_id应该是您班组中名为school School的外键。

这样查询为select创建了一个可用于排序的新值。 here是extra()的文档以防万一。

答案 2 :(得分:0)

有了可行的服务器端解决方案,我采用了客户端解决方案,通过jQuery重新排序列表:

$( "#sport-picker > li.first" ).after( $( "#sport-picker" ).find( "li > span:contains('2011-2012')" ).parent() );