我希望根据site
列hide = 0
中的不同值返回所有列,并按created
的日期对其进行排序。我知道只有PostgresSQL支持使用指定字段名称的distinct()
调用,但我正在运行MySQL。我有一个有效的SQL查询(它可能效率不高)但不确定如何将其转换为Django ORM。
models.py
from django.db import models
from django.utils import timezone
# Create your models here.
class Results(models.Model):
user_ip = models.GenericIPAddressField(unpack_ipv4=True)
site_ip = models.GenericIPAddressField(unpack_ipv4=True)
site = models.URLField()
reason = models.CharField(max_length=50)
hide = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.site
表格结构:
mysql > SHOW CREATE TABLE results\G
*************************** 1. row ***************************
Table: results
Create Table: CREATE TABLE `results` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_ip` char(39) NOT NULL,
`site_ip` char(39) NOT NULL,
`site` varchar(200) NOT NULL,
`reason` varchar(50) NOT NULL,
`hide` tinyint(1) NOT NULL,
`created` datetime(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=836 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
SQL查询:
SELECT * FROM
(
SELECT site, MAX(created) created
FROM results
GROUP BY site
ORDER BY MAX(created) DESC
LIMIT 10
) _d
JOIN results USING (site, created)
ORDER BY _d.created DESC
答案 0 :(得分:0)
有一个模块允许您对Django模型进行分组,并且仍然可以在结果中使用QuerySet:https://github.com/kako-nawao/django-group-by
例如:
from django_group_by import GroupByMixin
class ResultsQuerySet(QuerySet, GroupByMixin):
pass
class Results(Model):
# your model
class GroupedResultsListView(ListView):
template_name = 'xxx/results.html'
model = Results
def get_queryset(self):
return Results.objects.group_by('site').annotate(
max_created=Max('created')).order_by(
'created').distinct()
# order by 'max_created' might also work
'XXX / results.html'
<ul>
{% for result in object_list %}
<li>
<h2>{{ result.site }}</td>
<p>{{ result.max_created }}</p>
</li>
{% endfor %}
</ul>
annotate
/ aggregate
基本Django查询的不同之处在于使用了相关字段的属性,例如result.site
。您还可以在一个查询中按多个属性进行分组,例如
Results.objects.group_by('site', 'user_ip')
如果您需要已组合在一起的实例的PK,请添加以下注释:
.annotate(pks=ArrayAgg('id'))
注意:ArrayAgg
是Postgres特定的功能,可从Django 1.9开始提供:https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/aggregates/#arrayagg
答案 1 :(得分:0)
我有一个解决方法,但我想知道是否有更好的方法,因为这需要两个数据库命中:
{{1}}