2017-10-18 1 views
0

다른 모델의 두 가지 쿼리 세트를 하나로 결합해야합니다.두 개의 Querysets을 다른 모델의 하나로 결합하는 방법은 무엇입니까?

|&를 사용하려면,하지만이 chainlist를 사용하려면 동일한 모델

에서 검색어 세트에서만 작동하지만 이것이의 검색어 방법의 일부를 빼앗아 : 나는 온라인 찾은 대부분의 제안 된 솔루션은 , 그리고 내 프로젝트의 코드가 구조화되어 있기 때문에 나는 그것을 바꿀 수 없다. 나는 그것을 시도하고 작동하지 않았다.

나는 약 Q에 대해 읽었지 만, 내가 원하는 것을 성취하기 위해 그것을 어떻게 적용 할 수 있는지는 분명하지 않다.

기본적으로 다른 모델의 두 가지 쿼리 세트를 목록이 아닌 세 번째 쿼리 세트로 결합해야합니다. 필드 이름을 공유하기 때문에 Q과 같이 유용합니다. 예 :

queryset_1 = Cars.objects.all().filter(color='red') 
queryset_2 = Horses.objects.all() 

queryset_3 = queryset_1 + queryset_2 

queryset_3.order_by('date') 
+0

이 작업을 수행 할 수 없습니다. 정의에 의한 쿼리 세트는 단일 모델의 개체 집합입니다. –

답변

1

불행히도 데이터베이스 또는 쿼리 세트 수준에서는이 두 가지가 동일한 데이터베이스 테이블에 존재하지 않으므로 수행 할 수 없습니다. 당신은 파이썬 측면에서 그것을 할 수 있습니다 (비록 느리고보다 계산적으로 많이 사용합니다). 자동차와 말 모두가 "날짜"속성을 가지고 있다고 가정

, 당신은이 작업을 수행 할 수 있습니다

cars = Cars.objects.all().filter(color='red') 
horses = Horses.objects.all() 
all_things = list(cars) + list(horses) 
sorted_things = sorted(all_things, key=lambda x: x.date) 

(데이터베이스 수준에서 비효율적이다) 또 다른 옵션은 모두가 같은 상속하게하는 것 비 추상적 모델. 그들을 통해 반복 필요에 따라 (할미새 페이지를 처리하는 방법과 유사 각각의 특정 항목을 잡아 동안 그와

class Item(models.Model): 
    date = models.DateTimeFiedl() 
    item_type = models.CharField(max_length=255) 

    def get_instance(self): 
     if self.item_type = 'car': 
      return Car.objects.get(id=self.id) 
     elif self.item_type == 'horse': 
      return Horse.objects.get(id=self.id) 

class Car(Item): 
    color = models.CharField(max_length=12) 

    def save(self, *args, **kwargs): 
     self.item_type = 'car' 
     super(Car, self).save(*args, **kwargs) 

class Horse(Item): 
    breed = models.CharField(max_length=25) 

    def save(self, *args, **kwargs): 
     self.item_type = 'horse' 
     super(Horse, self).save(*args, **kwargs) 

, 당신은

items = Item.objects.all().order_by('date') 
for item in items: 
    print(type(item)) # Always "Item" 
    actual_item = item.get_instance() 
    if type(actual_item) == Car: 
     print("I am a car") 
    else: 
     print("I am a horse") 

을 수행 할 수 있습니다, 당신은에 따라 개체를 잡아하는 편리한 방법을 그 부모 클래스)

2

이 쿼리 세트가 정말로 필요한 경우 모델 수정이 잘못되었을 수 있으므로 모델을 잘못 수정 한 것보다 관리가 지루할 수있는 위험이 있으므로 모델을 잘못 설계 한 것일 수 있습니다. 제 제안은 Car와 Horse를 대체하는 단일 모델을 설정하는 것입니다 (일부 필드가 각 사례의 인스턴스에 대해 비어있는 경우에도). 두 필드를 쉽게 식별 할 수있는 별도의 필드가 있어야합니다. 예 :

class Vehicle(models.Model): 
    category = models.IntegerField(
     choices=[(10, 'Horse'), (20, 'Car'), (30, 'Bicycle')] 
    ) 
    # other fields here... 
+0

제 생각에는 데이터베이스 정규화라고합니다 : https://en.wikipedia.org/wiki/Database_normalization – White

+0

맞습니다! 그것이 바로 그 것이다. – davecaputo

+0

내 솔루션은 제안하는 방법과 목록을 사용하는 방식을 혼합 한 것입니다. 그러나 당신의 의견은 옳습니다. 프로젝트는 코드 조직 측면에서 다소 이상한 방식으로 진화했습니다. –

관련 문제