Django查询使用创建的字段对记录进行分组

时间:2017-02-09 13:38:20

标签: python django

models.py

class Post(models.Model):
    caption = models.CharField(max_lenght=200)
    description = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

我正在寻找一个返回结果的Django查询:

data = {
    "YYYY-MM-DD": [{<post data one>}, {<post data two>}],
    "YYYY-MM-DD": [{<post data one>}, {<post data two>}],
    "YYYY-MM-DD": [{<post data one>}, {<post data two>}],
}

“YYYY-MM-DD”是created模型中Post字段的日期值

2 个答案:

答案 0 :(得分:1)

我认为你可以使用python模块中的groupby来处理它。

我会给你一个例子;

>>> rows = Post.objects.published().values_list('id', 'created')
>>> rows
<QuerySet [
  (100, datetime.datetime(2017, 2, 9, 14, 35, 9, 358, tzinfo=<UTC>)), 
  (99, datetime.datetime(2017, 2, 9, 14, 35, 0, 760347, tzinfo=<UTC>)), 
  (98, datetime.datetime(2017, 1, 22, 3, 32, 18, 570201, tzinfo=<UTC>)), 
  (97, datetime.datetime(2017, 1, 3, 0, 44, 35, 277663, tzinfo=<UTC>)), 
  (96, datetime.datetime(2017, 1, 1, 14, 18, 30, 920143, tzinfo=<UTC>)),
  (95, datetime.datetime(2016, 12, 24, 3, 31, 2, 370658, tzinfo=<UTC>)),
  '...(remaining elements truncated)...']>
>>>
>>> from itertools import groupby
>>> items = []
>>> for k, v in groupby(rows, key=lambda row: row[1].strftime('%Y-%m-%d')):
...     data = dict({k: list(dict(v).keys()) })
...     items.append(data)
...     print(data)
... 
{'2017-02-09': [99, 100]}
{'2017-01-22': [98]}
{'2017-01-03': [97]}
{'2016-10-09': [81]}
{'2016-10-07': [80, 79]}
{'2016-10-05': [78]}
{'2016-10-04': [77]}
{'2016-10-02': [1, 2, 3, 4, 5, 6, 7]}
>>> items
[
  {'2017-02-09': [99, 100]}
  {'2017-01-22': [98]}
  {'2017-01-03': [97]}
  {'2016-10-09': [81]}
  {'2016-10-07': [80, 79]}
  {'2016-10-05': [78]}
  {'2016-10-04': [77]}
  {'2016-10-02': [1, 2, 3, 4, 5, 6, 7]}
]

我之前的测试,对象的值为id/pk。您还可以创建一个函数来获取titleslug或其他..例如:

>>> def get_titles(ids):
...     final_titles = []
...     for id in ids:
...         final_titles.append(Post.objects.get(id=id).title)
...     return final_titles
>>>
>>> items = []
>>> for k, v in groupby(rows, key=lambda row: row[1].strftime('%Y-%m-%d')):
...     titles = get_titles(list(dict(v).keys()))
...     items.append(dict({k: titles}))
>>> items
[
  {'2017-02-09': ['Test Post 1', 'Test Post 2']}, 
  {'2017-01-22': ['Fixed DNS PROBE on Ubuntu']}, 
  {'2017-01-03': ['Django: Custom safe excludes from dangerous XSS Injection']}, 
  {'2017-01-01': ['DracEditor - Django Markdown Editor built for Dracos Linux']}, 
  {'2016-12-24': ['Top 10 Python libraries of 2016']}, 
  {'2016-12-19': ['How to custom html choose image upload for django markdownx']}, 
  {'2016-12-18': ['Command to handle deploy Django with quickly']}

  ....
]
  

默认情况下,如果您尝试使用final_titles.append(Post.objects.get(id=id)),请在string

内的def __unicode__(self):def __str__(self):功能中返回models.Post

最后,简单地从对象获取元数据。

def get_data(ids):
    final_data = []
    for id in ids:
        post = Post.objects.get(id=id)
        final_data.append({'title': post.title, 'created': post.created, 'slug': post.slug})
    return final_data

items = []
rows = Post.objects.published().values_list('id', 'created')

for k, v in groupby(rows, key=lambda row: row[1].strftime('%Y-%m-%d')):
    data = get_data(list(dict(v).keys()))
    items.append(dict({k: data}))

items;

的结果
[
  {
    '2017-02-09': [
      {
        'created': datetime.datetime(2017, 2, 9, 3, 32, 18, 570201, tzinfo=<UTC>),
        'title': 'Test Post 1',
        'slug': 'test-post-1'
      },
      {
        'created': datetime.datetime(2017, 2, 9, 2, 21, 9, 570201, tzinfo=<UTC>),
        'title': 'Test Post 2',
        'slug': 'test-post-2'
      }
    ]
  }, 
  {
    '2017-01-22': [
      {
        'created': datetime.datetime(2017, 1, 22, 3, 32, 18, 570201, tzinfo=<UTC>), 
        'title': 'Fixed DNS PROBE on Ubuntu', 
        'slug': 'fixed-dns-probe-on-ubuntu'
      }
    ]
  }, 
  {
    '2017-01-03': [
      {
        'created': datetime.datetime(2017, 1, 3, 0, 44, 35, 277663, tzinfo=<UTC>), 
        'title': 'Django: Custom safe excludes from dangerous XSS Injection', 
        'slug': 'django-custom-safe-excludes-from-dangerous-xss-injection'
      }
    ]
  }, ....
]

答案 1 :(得分:0)

查看regroup模板标记。

这样的事情应该有效:

{% regroup posts by created as post_list %}

<ul>
{% for row in post_list %}
    <li>{{ post_list.grouper }}
    <ul>
        {% for created in row.list %}
          <li>{{ created.caption }}: {{ created.description }}</li>
        {% endfor %}
    </ul>
    </li>
{% endfor %}
</ul>