2016-07-24 1 views
0

외래 키가있는 테이블이 있습니다. (나는 의도적으로 일대일이 아닌 외래 키를 사용한다.)
이 나는 ​​주문 모델이 있습니다django - 하나의 관련 개체가 생성되었는지, 경쟁 조건인지 확인하십시오.

class Order: 
    name = models.CharField(max_length=50) 
    user = models.ForeignKey(User) 
    active = models.BooleanField(default=True) 
    # more fields.. 

을 그리고이 모델의 하나의 인스턴스는 사용자 당 존재하는 것을 나는 원한다.

저장하는 간단한 양식 (및보기)이 있습니다. 그리고이 코드가 있습니다

try: 
    instance = Order.objects.get(user=user) 
except Order.DoesNotExist: 
    instance = None 
form = OrderForm(instance=instance) 

을하지만 눈치가 동시에 클라이언트 불이 결과의 요청은 (두 개의 인스턴스 내 다음과 같은 검증에도 불구하고, 생성 된 얻을 수 있습니다 (나는 아약스를 사용할 때 것으로 나타났습니다) 경우 기존의 것을 갱신한다고 가정).

다른 코드가 사용자 당이 모델의 인스턴스를 하나만 예상하므로 매우 중요합니다. 어떻게 그것을 장고에서 시행 할 수 있습니까? 내 시야에서 다음을 시도했습니다.

@method_decorator(transaction.atomic, name='dispatch') 

하지만 작동하지 않았습니다. 그리고 내가 말했듯이, 나는 일대일 필드를 사용할 수 없다.

+0

Django REST Framework를 사용합니까? 난 serializer 유효성 검사와 함께 이것을 달성 할 수있을 것 같아요. – fodma1

+0

불행히도 당신이 한 - OneToOneField를 사용하는 경우 – user3599803

+0

을 사용하지 말고, Order.objects.get_or_create()를 사용하여 100 % 당신이 lock ('select_for_update()') https://docs.djangoproject.com/ko/1.9/ref/models/querysets/#select-for-update] – Jerzyk

답변

1

당신은 unique_together와 데이터베이스 수준 및 Null 허용 필드에서 유니시티을 적용 할 수 있습니다

class Order: 
    name = models.CharField(max_length=50) 
    user = models.ForeignKey(User) 
    active = models.NullBooleanField(default=True) 

    class Meta: 
     unique_together = (('user', 'active'),) 

비결은 비활성 주문 activeNone에 대신 False을 설정하는 것입니다. NULL 값은 데이터베이스 레벨에서 동일한 것으로 간주되지 않으므로 사용자는 여러 개의 비활성 주문을 가질 수 있지만 활성 주문은 하나만 가질 수 있습니다.

+0

사용자가 둘 이상의 비활성 주문을 가질 수 있기 때문에이 기능이 작동하지 않습니다. –

+0

예, 가능합니다. 대답 : – aumo

+0

을 읽으십시오. 나는 여전히 "코드"제약 조건 검사를 찾을 수 있는지, 즉 외래 키에 속하는이 테이블의 모든 레코드를 잠그고 싶습니다. – user3599803

0

사용자의 경우 unique=true을 설정할 수 있습니다. 그러면 사용자 당 단 하나의 주문 만 보장됩니다.

class Order: 
    name = models.CharField(max_length=50) 
    user = models.ForeignKey(User, unique=true) 
    active = models.BooleanField(default=True) 
+0

일대일 필드 설정과 동일합니다. 그리고 말했듯이 나는 그것을 사용할 수 없다. 그 이유는 '활성'필드입니다. 사용자는 하나만 활성 상태이지만 여러 개의 '비활성'상태를 가질 수 있습니다. 그래서 데이터베이스 수준에서 적용 할 수 없습니다 - 나는 그것을 선호합니다. 트랜잭션 또는 잠금 기반 솔루션이 필요하며 작동하는 것을 찾을 수 없습니다. – user3599803

관련 문제