如何根据以前的查询组织查询?

时间:2015-06-03 21:00:11

标签: django

例如,我有一个呈现某些对象的ListView,我也有一些按钮使用ajax来呈现具有不同过滤器的这些对象,例如按字母顺序或其他字段过滤。使用这些按钮时,它们返回ListView对象的过滤结果。如果ListView以发布的顺序返回对象,则按钮将执行:

in published order -> by name -> by views

如何制作如下序列:

in publish order publish -> by name -> by views(by name also) -> by something else(by views also)

我认为有可能用ajax请求来攻击一些变量,然后依赖于这个var返回另一个查询。但我不知道它是否是最好的方式,因为我可能对Django不太好。 那么这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

实施例

app/models.py

from django.db import models

class Entry(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)
    views = models.IntegerField()

    def __str__(self):
        return self.title

app/urls.py(如果您想尝试此示例,请不要忘记在app.urls中添加project.url

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

app/views.py

from django.shortcuts import render
from .models import Entry

def index(request):
    # fields in which we want to order query
    ordering_fields = ['pub_date', 'views', 'title']

    # order_query is field names with dots between them
    order_query = request.GET.get('o')

    # ordering is something like ['views', 'tile']
    ordering = []
    if order_query:
        ordering = [x for x in order_query.split('.') if x in ordering_fields]
    entries = Entry.objects.order_by(*ordering)

    # look at index.html to understand, what query_strings is for
    query_strings = {}
    for field in ordering_fields:
        if field in ordering:
            # remove field
            idx = ordering.index(field)
            query_strings[field] = '.'.join(ordering[:idx]+ordering[idx+1:])
        else:
            # add fieild
            query_strings[field] = '.'.join(ordering + [field])

    return render(request, 'app/index.html', {
        'entries': entries,
        'query_strings': query_strings,
        'ordering': ordering
    })

app/templates/app/index.html

<!doctype html>
<head>
  <meta charset="utf-8">
  <title>Entries</title>
  <style>
  table {
    border: 1px solid #333;
  }
  td, th {
    border: 1px solid #333;
    padding: 5px 10px
  }
  </style>
</head>
<body>
  <p><a href="{% url 'index' %}">Index</a></p>
  <p>
    Sort by:
    <a href="?o={{ query_strings.title }}">Title</a>{% if 'title' in ordering %}*{% endif %} |
    <a href="?o={{ query_strings.views }}">Views</a>{% if 'views' in ordering %}*{% endif %} |
    <a href="?o={{ query_strings.pub_date }}">Pub date</a>{% if 'pub_date' in ordering %}*{% endif %}
  </p>
  <table>
    <thead>
      <tr>
        <th>Title</th>
        <th>Views</th>
        <th>Pub date</th>
      </tr>
    </thead>
    <tbody>
    {% for entry in entries %}
      <tr>
        <td>{{ entry.title }}</td>
        <td>{{ entry.views }}</td>
        <td>{{ entry.pub_date }}</td>
      </tr>
    {% endfor %}
    </tbody>
  </table>
</body>

订购网址如下:?o=title?o=pub_date.views?o=views.title.pub_date

在最后一种情况下,结果按views排序,然后按title排序,然后按pub_date排序。标题的链接为?o=views.pub_date,视图为?o=views.title,发布日期为o?=views.title