2016-06-21 4 views
0

다음 SQL 쿼리를 Django QuerySet 호출로 변환하는 방법을 보여줄 수 있습니까? 나는 Django에 익숙하지 않고 원시 쿼리를 사용할 수 있지만,이 쿼리가 어떻게 원시 Django 호출로 작성 될 수 있는지 아는 것은 흥미 롭습니다.원시 SQL을 Django QuerySet으로 변환

두 모델이 있습니다. 사용자 & 프로필 1 : 1 두 개 이상의 프로필에 동일한 전화 번호가 표시되면 프로필에서 사용자 및 전화로 이메일을 가져와야합니다. 내가하려고 여기에서

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') 

.. 그리고 그 결과는 다음과 같습니다 다음 빈 결과가 될 것입니다 쿼리에 .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' 모델의 관련 부분을 보여줄 수 있다면 도움이 될 것입니다.하지만 여기서 보여준 결과는 전화 번호가 하나 뿐이므로 왜 필터를 추가해도 결과가 없습니다. – 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