2009-04-13 6 views
6

몇 가지 쿼리를 작성하여 Django 모델 객체의 목록을 작성합니다. 그런 다음 복제본을 제거하고 싶습니다. (이 모든 객체는 auto_increment int PK와 동일한 유형입니다.) 해시 가능하지 않기 때문에 set()을 사용할 수 없습니다.장고 모델 - 사실 후 PK로 중복 값을 필터링하는 방법?

이렇게 빠르고 쉬운 방법이 있습니까? id를 키로 사용하는 목록 대신 dict을 사용하는 것을 고려하고 있습니다.

답변

6

빠르고 쉬운 방법이 있습니까? id를 키로 사용하는 목록 대신 dict을 사용하는 것을 고려하고 있습니다.

몇 가지 쿼리를 작성하는 현재 구조에 고정되어 있다면 정확히 그럴 것입니다. 다음 간단하게 dictionary.values()는 당신의 명부를 돌려 보낼 것이다.

좀 더 융통성이 있다면 Q 개체를 사용하지 않으시겠습니까? 실제로 쿼리를 만드는 대신 각 쿼리를 Q 개체에 저장하고 비트 또는 ("|")를 사용하여 단일 쿼리를 실행합니다. 이것은 목표를 달성하고 데이터베이스 히트를 저장합니다. 이 ID를 반환하도록합니다 (이 앱에있을 수있는 다른 해시 동작을 방해하지 않는 가정) 모델 정의에 __hash__ 기능을 추가하는 경우

Django Q objects

+0

이인가 : – wsorenson

+0

정말 그게 무슨 뜻인지 잘 모르겠다. 나는 당신이 그것을 필요로하는지 또는 외래 키 ID가 무엇을 가리키고 있는지 확실하지 않다. –

+0

Q 개체를 사용하여 여러 테이블과 스패닝 관계에서 개체를 검색 할 수있었습니다. – wsorenson

0

주문이 중요하지 않은 경우 dict을 사용하십시오.

3

당신은 설정을 사용할 수 있습니다

class MyModel(models.Model): 

    def __hash__(self): 
     return self.pk 
0

"중복"을 제거하는 방법은 "복제 된"방법을 정의하는 방법에 따라 다릅니다.

일치하는 모든 열 (PK 제외)을 원하면 목에 통증이 있습니다.

반면에 "자연 키"열 (또는 짧은 열 집합)이 있으면 쉽게 쿼리하고 제거 할 수있는 것보다 큽니다.

master = MyModel.objects.get(id=theMasterKey) 
dups = MyModel.objects.filter(fld1=master.fld1, fld2=master.fld2) 
dups.all().delete() 

중복 식별을 위해 더 짧은 키 필드 집합을 식별 할 수 있다면이 방법이 효과적입니다. 모델 객체가 아직 데이터베이스에 저장되지 않은 경우


편집, 당신은 이러한 키의 튜플에 사전을 만들 수 있습니다.

unique = {} 
... 
key = (anObject.fld1,anObject.fld2) 
if key not in unique: 
    unique[key]= anObject 
12

일반적으로 가능하면 모든 검색어를 하나의 검색어로 조합하는 것이 좋습니다. 예.첫 번째 쿼리가 중복 모델을 반환하는 경우

q = Model.objects.filter(Q(field1=f1)|Q(field2=f2)) 

대신

q1 = Models.object.filter(field1=f1) 
q2 = Models.object.filter(field2=f2) 

의 다음 별개의()

q = Model.objects.filter(Q(field1=f1)|Q(field2=f2)).distinct() 

쿼리 정말 하나의 명령으로 실행할 수없는 경우, 사용 당신은 다른 답변에서 권장되는 dict 또는 다른 기술을 사용하는 것에 의존해야합니다. 정확한 쿼리를 SO에 게시하고 단일 쿼리로 결합 할 수 있는지를 알면 도움이 될 수 있습니다. 내 경험상 대부분의 쿼리는 단일 쿼리 세트로 수행 할 수 있습니다. 외래 키 ID를 (종류의 여러 부분과 IN ​​쿼리 같은) 여러 테이블에서 오는 경우에 당신은 당신이 개체를 잡아 얼마나

dict(zip(map(lambda x: x.pk,items),items)).values() 
+1

Q 개체와 distinct() - 감사를 사용할 수있었습니다. – wsorenson

0

나는이 하나를 사용?