2016-06-21 12 views
0

次のSQLクエリをDjango QuerySet呼び出しに変換する方法を示す人がいますか?私はDjangoの初心者です。生のクエリを使用することもできますが、このクエリをネイティブDjango呼び出しとしてどのように記述できるのか興味深いです。生SQLをDjango QuerySetに変換する

2機種のユーザーがあります&プロファイル1:1 2つ以上のプロファイルに同じ電話番号が表示されている場合は、プロファイルからユーザーと電話から電子メールを取得する必要があります。私がしようとしたものをここで

SELECT GROUP_CONCAT(u.email) as emails, p.phone as phone_number FROM profile AS p JOIN auth_user AS u on u.id = p.user_id GROUP BY phone HAVING COUNT(phone) > 1

from myapp.models import Profile 
from django.db.models import Count 

Profile.objects 
     .exclude(phone='') 
     .annotate(phone_count=Count('phone')) 
     .values('phone') 

..and結果は次のとおりです。その後、空の結果がされるクエリに.filter(phone_count__gt=1)を追加する

[ 
    { 
    'phone': '***' 
    }, 
    { 
    'phone': '***' 
    } 
] 

場合返された(理由を理解していない)。

所望の出力は次のようになります。

[ 
    { 
     'phone': '***', 
     'emails': '[email protected]' 
    }, 
    {   
     'phone': '***', 
     'emails': '[email protected],[email protected]' 
    } 
    ] 

UPD

class Profile(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    phone = models.CharField(max_length=100, blank=True, null=True) 
+0

あなたはそれを自分で変換しようとした方法を示すべきです。 – Sayse

+0

@Sayseはさらに詳しい説明を追加しました。 – hustas88

+0

'Profile'モデルの関連部分を表示できれば助かりますが、ここで示した結果は1つの電話番号しか持たないので、なぜフィルタを追加しても結果が返されないのです – Sayse

答えて

0
from myapp.models import Profile 
from django.db.models import Count 

qs = Profile.objects.exclude(
    phone='' 
).exclude(
    phone__isnull=True 
).values('phone').annotate(
    phone_count=Count('user_id') 
).filter(
    phone_count__gt=1 
).values_list('phone', flat=True) 
# the above will get you a list of phone numbers that appear more than once 
# now get the user_ids, too, and add in the emails 
qs = Profile.objects.filter(phone__in=qs).values_list('user__email', 'phone') 
# now convert to a dict 
from collections import defaultdict 
data = defaultdict(list) 
for email, phone in qs: 
    data[phone].append(email) 
# now convert to desired format 
result = [{ 
    'phone': phone, 
    'emails': ','.join(emails), 
} for phone, emails in data.itervalues()] 

# Of course, you could always just use raw and do a raw 
# SQL query as described here: https://docs.djangoproject.com/en/1.9/topics/db/sql/#executing-custom-sql-directly 
+0

になるのはどういう値ですか?これは本当に役に立ちます! – hustas88

関連する問題