2017-07-13 7 views
0

sitehide = 0からの別の値に基づいてすべての列を返したい場合は、createdから日付順に返します。私はdistinct()指定されたフィールド名を持つ呼び出しは現在PostgresSQLによってのみサポートされているが、私はMySQLを実行していることを認識しています。私は実際のSQLクエリ(それはおそらく非常に効率的ではない)が、Django ORMに変換する方法がわからない。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

ormが必要な場合は、models.pyにフィールド – Exprator

+0

を投稿する必要があります。@Expratorが私の 'models.py'を追加しました – HTF

+0

hget_scanは何ですか?それのためのモデルがありますか? – Exprator

答えて

0

モジュール番目があります例えば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> 
グループDjangoのモデルにあなたを可能にし、まだ結果にクエリセットで作業で

annotate/aggregateの基本的なDjangoクエリとの違いは、関連するフィールドの属性、例えば。 result.site。 1つのクエリで複数の属性をグループ化することもできます(例:

.annotate(pks=ArrayAgg('id')) 

注:ArrayAggは、以降のDjango 1.9から利用できるPostgresの特定の機能、次のとおりです。https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/aggregates/#arrayagg

あなたが一緒にグループ化されたインスタンスのPKのが必要な場合は

Results.objects.group_by('site', 'user_ip') 

は、以下の注釈を追加します

+0

外部モジュールなしでこれを行う方法はありますか? – HTF

0

私は回避策を持っていますが、これには2つのデータベースヒットが必要なため、より良い方法があるかどうか疑問に思っています:

views.py 

recent_results_ids = [] 
[recent_results_ids.append(i.id) for i in Results.objects.raw('SELECT MAX(id) id FROM results WHERE hide = 0 GROUP BY site ORDER BY MAX(created) DESC LIMIT 10')] 
recent_results = Results.objects.filter(id__in=recent_results_ids).order_by('-id') 
関連する問題