2016-08-22 2 views
0
class Order(models.Model): 
     # Some fields.. 
     status = models.IntegerField() 
     user = models.ForeignKey(User) 

네 개의 값 얻을 수있는 상태 필드 :와 나는 단일 행 (튜플)를 반환하는 쿼리를 수행 할 1,2,3,4장고 다수 존재() 집계

을, 에 따라 지표,이 우선 순위에서

if in the queryset there is a row with status=1, return 1 
elif there's row with status=3, return 3 
elif there's row with status=4, return 4 
elif there's row with status=2, return 2 

(즉,이 순서로, 스위치의 경우 작동하는 방법과 유사). 특정 사용자에게 상태 메시지를 표시하도록 쿼리합니다. 그래서 다음과 같이 시작해야합니다 :

Order.objects.filter(user=request.user) # ...? .aggregate() maybe ? 

그리고 나는 어떤 Order 객체도 필요로하지 않습니다.
db 레벨에서는 Case과 같은 것으로 생각되지만 장고와 함께 작동시키지는 못했습니다.

편집 : 더 나은 설명하기 위해, 나는 .. 나는 4 개 쿼리를 수행하지 않으려 분명히 그

if Order.objects.filter(user=request.user, status=1).exists(): 
    return 1 
elif Order.objects.filter(user=request.user, status=3).exists(): 
    return 3 
elif Order.objects.filter(user=request.user, status=4).exists(): 
    return 4 
elif Order.objects.filter(user=request.user, status=2).exists(): 
    return 2 

그러나 같은

답변

1
order_statuses = Order.objects.filter(user=request.user).values_list('status', flat=True) 

이렇게하면 상태 목록이 표시됩니다. 대신 데이터베이스에 추가로드 증가에

if 1 in order_statuses: 
    return 1 
elif 2 in order_statuses: 
    return 3 
elif 3 in order_statuses: 
    return 4 
elif 4 in order_statuses: 
    return 2 

이 방법은 당신이 당신의 장고 서버에 계산을 할 수 있습니다 : 지금 당신은으로 확인할 수 있습니다.

2
Order.objects.annotate(order_status=models.Case(
    models.When(status=1, then=0), 
    models.When(status=3, then=1), 
    models.When(status=4, then=2), 
    models.When(status=2, then=3), 
    default=models.F('status'), 
    output_field=models.IntegerField(), 
),).aggregate(models.Min('order_status')) 

그것을 할 그리고 매핑

상태들에 대한 몇 가지 딕셔너리를 필요로 할 수
+0

을 내가 필드의 숫자 값에 의존하지 선호합니다. 둘째, status = 3이고 status = 2 인 행이있는 것처럼 3이 리턴되어야하는 것처럼 작동하지 않습니다. – user3599803

0

이 작업을 수행 할 수 있습니다

# This will return a value of None, if no matching Order object exists, 
# or the lowest status that exists: 
return Order.objects.filter(
    user=request.user 
).order_by(
    'status' 
).values_list(
    'status', flat=True 
).first()