2011-04-13 4 views
0

X 모델의 필드가 n (정수)이라고 가정 해 보겠습니다. 이제 nm (정수) 필드가있는 Y 모델도 있습니다. Django ORM을 사용하여 m의 주어진 값에 대해 x.n = y.ny.m = m과 같은 y (모델 Y)이 존재하도록 x (모델 X)을 선택할 수 있습니까?Django 모델의 임의의 조인

ForeignKey 두 모델 간의 관계 또는 그와 비슷한 것을 소개하지 마십시오. 모델을 수정하지 않고도이 작업을 수행 할 수 있는지 구체적으로 알고 싶습니다. 내가 작업하고있는 정확한 경우에 주어진 관계는 일반적인 것입니다. 그리고 일반적인 관계의 반대편은 무엇이든 될 수 있습니다. 따라서 문서에 따르면 다른 모델에 여러 번 넣을 수는 없습니다.

+0

는 나만 아니면이 기능에 심각한 차이입니다 (나는 그것을 테스트하지 않았다)? 사소한 일이 아닌가요? 나는 그들이 svn에 자신의 코드를 유지한다는 사실이 나쁜 징후라고 생각하기 시작한다. – julkiewicz

+0

Django 세계에서 생각하는 것보다 덜 제한적입니다. 임의의 조인을 원하면 원시 SQL (실제 모델 오브젝트 리턴)이 있습니다. 그리고 ... 근심과 의욕이 너무 좋아요.하지만 오픈 소스 프로젝트에 대해 가장 불평하는 사람이 소스 코드 제어 도구에 대한 취향이라면, 하나는 낙원에 도달했습니다. – Christophe

+0

@Christophe 원시 SQL의 문제점은 직접 열 이름을 손으로 생성해야한다는 것입니다. 그리고 나는 현재의 거래를 더럽다고 생각합니다. 나는 그것이 가능하다는 것을 안다. 그러나 내가 약간 비표준적인 것을 할 필요가있을 때마다 SQL을 수동으로 작성해야한다. 오히려 ORM을 사용하지 않을 것이다. Django ORM과 함께 꽤 오랜 시간을 보낸 후, 디자인에 의해 심각하게 손상되었다고 생각합니다. – julkiewicz

답변

4

나는 이것이 ng extraQuerySet 방법.

X.objects.extra(where=["x.n in (select y.n from y where y.m = '%s')"], params=['m_value']) 
+0

글쎄, 이름에 몇 가지 사소한 변경 후 작동하지 않습니다. 내가 읽은 바에 따르면 일반 JOIN보다 성능이 좋습니다. 감사. – julkiewicz

+0

queryset.query.get_initial_alias() 쿼리의 기본 테이블에 할당 된 별칭을 가져옵니다. 또한 SomeModel._meta.db_table에는 모든 모델의 기본 테이블 이름이 있습니다. –

1
당신이 사용하는 원시 SQL 할 수

: 언급 한 바와 같이 :

class X(models.Model): 
    n = models.IntegerField() 

class Y(models.Model): 
    n = models.IntegerField() 
    m = models.IntegerField() 

xs = X.objects.filter(n__in=Y.objects.filter(m=m).values_list('n')).distinct() 

편집 :

def my_custom_sql(m): 
    from django.db import connection, transaction 
    cursor = connection.cursor() 

    # Data retrieval operation - no commit required 

    command = """SELECT * 
     FROM tX 
INNER JOIN tY 
     ON (tX.n=tY.n AND tY.m=%s)""" 

    cursor.execute(command % str(m)) 
    rows = cursor.fetchall() 

    return rows 

ORM을 사용하여, 당신이 사용 values_listin 필터를 할 수 있다고 생각 주석에서이 방법은 db를 많이 쳤을 것입니다

+1

참고 사항 : @kriegar가 수행 한 두 번째 방법으로 각 X 개체의 DB에 O (n + 1) 히트가 발생합니다. 그것을 강력히 권고 할 것입니다. 그가 게시 한 첫 번째 방법을 사용해야합니다. –

+0

글쎄, 두 번째 방법의 문제는 DB에 매우 긴 값 목록을 전송할 때 매우 비효율적이라는 것입니다. 첫 번째 방법은 선택의 여지가 없습니다. 어쩌면 나는 그것을 매니저로 꾸리려고 노력할 것이다. 그러나 나는이 프레임 워크에 대한 증오를 시작한다고 생각한다. 아 !!! – julkiewicz

관련 문제