有没有办法使用django通用视图和一些智能urlpatterns对查询进行快速排序/排序?

有没有办法使用django通用视图和一些智能urlpatterns对查询进行快速排序/排序?,django,Django,假设我有一个django模型,如下所示: class Event(CommonSettings) : author = models.ForeignKey(User) timestamp = models.DateTimeField(auto_now_add=True) event_type = models.ForeignKey(Event_Type, verbose_name="Event type") text_field = models

假设我有一个django模型,如下所示:

class Event(CommonSettings) :
    author      = models.ForeignKey(User)
    timestamp   = models.DateTimeField(auto_now_add=True)
    event_type  = models.ForeignKey(Event_Type, verbose_name="Event type")
    text_field  = models.TextField()
    flag_box    = models.BooleanField()
    time        = models.TimeField()
    date        = models.DateField()
    project  = models.ForeignKey(Project)
现在,默认情况下,我有一个按时间和日期对所有事件排序的视图:

event_list = Event.objects.filter().order_by('-date', '-time')
但是,用户可能只想按时间、日期或按升序而不是降序对事件进行排序。我知道我可以创建匹配所有这些情况的urlpatterns,然后将这些选项传递给我的视图,但是我觉得我在这里重新发明轮子。django管理站点可以直接完成所有这些工作

因此,我的问题是:是否有一种聪明、简单的方法可以以通用的方式完成这项工作,还是我必须为我的模型/视图/模板硬编码

是的,我确实找到了这样的解决办法(https://gist.github.com/386835)但这意味着你要用三个不同的项目来实现一件事——对于这么简单的事情来说,这似乎是一个太复杂的解决方案

EDIT1: 如何更改模板,以便组合多个过滤器?现在我有

<a href="?sort=desc">Desc</a>
<a href="?sort=asc">Asc</a> 
而且是

paginate_by
选择权

我试过:

<a href="?sort={{sort_dir}}?page={{ page_obj.previous_page_number }}" class="prev">prev</a>
<a href="?sort={{sort_dir}}?page={{ page_obj.next_page_number }}" class="next">{% trans "next" %}</a>


但是链接就是不起作用(什么也没发生)。也许你需要对“object\u list”做一些特殊的处理?

我认为这并不像你想象的那么多——你可以使用变量,而不是显式地创建单独的url模式。如果您查看django管理员如何处理它,他们会将请求变量附加到url上,如
?ot=asc&o=2
,这对应于第2列中的升序排序。当然,如果您要设计一个特定的页面,您还可以使用更具可读性的命名。因此,我不需要对类别进行编号,而是执行
?sort=desc&order\u by=date
,然后在视图中放置一个正则表达式以匹配不同的可能性。比如:

order = re.match(r"(?:date|time|name)$", request.GET['order_by'])
if request.GET['sort'] == 'desc':
    order = '-' + order
results = Event.objects.filter().order_by(order)
您可以按照建议使用regexp作为url模式匹配器,但更常见的是让url本身表示您所在站点的哪个部分(即
website.com/events/
),url请求变量表示内容的显示方式(即
?order\u by=date&sort=desc

希望有帮助

编辑:对于问题的第二部分,使用Django的模板系统(读取变量),而不仅仅是html。我可以想出几种方法来实现这一点,具体取决于个人偏好和您希望UI发挥作用的方式(即,每当用户选择过滤器,或用户选择表单中的所有过滤器选项,然后提交,页面只需重新加载一次,等等),页面就会加载新变量。在这种情况下,您可以执行以下操作:

<a href="?sort_by=asc&order_by={{order}}">Ascending</a>
<a href="?sort_by=desc&order_by={{order}}">Descending</a>

<a href="?sort_by={{sort}}&order_by=name">Name</a>
<a href="?sort_by={{sort}}&order_by=date">Date</a>

然后在视图中,确保您的render_to_响应参数包含如下字典:
{'order':request.GET['order_by'],'sort':request.GET['sort_by'],}


不幸的是,(如果我错了,请有人纠正我)我不认为有模板标记可以生成带有request.GET参数的url-url标记
{%url name\u of_view order\u by=name sort\u by=desc%}
会生成“path/to/name\u of_view/name/desc/”,但我认为没有标记可以生成“path/to/name\u of_view?order_by=name&sort_by=desc”。不过,为它编写一个自定义标记是相当容易的(如果django代码片段或其他东西上已经有一个标记,我也不会感到惊讶,尽管我只是在谷歌上快速搜索了一下,什么也没找到).

我觉得这已经是正确的方向了。谢谢!但是,对于更复杂的情况,您不仅显示“事件”,而且还显示“注释”。这两个字段都是可排序的。我该如何实现这一点?在这种情况下,不清楚该方向属于两个模型中的哪一个。我不确定是否理解-您是说“事件”“注释”和“注释”是显示在同一页面上的两种不同型号?在这种情况下,我只使用4个变量而不是2个变量来定义排序。类似于:
?事件\u顺序=日期和注释\u顺序=时间和事件\u排序=asc和注释\u排序=描述
不幸的是,这不适用于“对象列表”的分页选项。见我的编辑2。
order = re.match(r"(?:date|time|name)$", request.GET['order_by'])
if request.GET['sort'] == 'desc':
    order = '-' + order
results = Event.objects.filter().order_by(order)
<a href="?sort_by=asc&order_by={{order}}">Ascending</a>
<a href="?sort_by=desc&order_by={{order}}">Descending</a>

<a href="?sort_by={{sort}}&order_by=name">Name</a>
<a href="?sort_by={{sort}}&order_by=date">Date</a>