2009-11-27 4 views
0

, 나는 이런 식으로 뭔가 할 노력하고있어 :왜이 모델을 다른 모델에 추가하기 전에이 모델을 저장해야합니까? 장고

# if form is valid ... 
article = form.save(commit=False) 
article.author = req.user 

product_name = form.cleaned_data['product_name'] 
try: 
    article.product = Component.objects.get(name=product_name) 
except: 
    article.product = Component(name=product_name) 

article.save() 
# do some more form processing ... 

을하지만 그것은 나 알려줍니다

열 "PRODUCT_ID"에서

null 값은하지 null이 제약 조건을 위반

그러나 이것이 왜 문제인지 이해할 수 없습니다. article.save()이 호출되면 제품을 으로 만들고 (생성하고 ID를 생성 할 수 있어야합니다.

나는 except 블록에이 코드를 사용하여이 문제를 해결하려면 얻을 수 있습니다 :

product = Component(name=product_name) 
product.save() 
article.product = product 

article.save()이 실패 할 경우, 이미 새로운 구성 요소/제품을 만든 것이기 때문에 그러나이 날 우려하는 이유입니다. 나는 그들이 성공하거나 실패하기를 바란다.

이 문제를 해결할 수있는 좋은 방법이 있습니까?

+1

참고 사항 : article.product = Component.objects.create (name = product_name) 조금 깔끔합니다. – michael

+0

@michael : 오!내가 그걸 할 수 있는지 몰랐다. 적어도 조금은 나아졌습니다. – mpen

답변

1

당신은 사용하여이 문제를 얻을 수 :

target_product, created_flag = Component.objects.get_or_create(name=product_name) 
article.product = target_product 

내가 하나를 만들 경우 get_or_create()는, 객체의 ID를 설정합니다 확신한다.

또한 Article 테이블에서 빈 FK 관계가 마음에 들지 않으면 null=True을 정의에 추가 할 수 있습니다.

+0

'created_flag'에 신경 쓰지 않으면 어떻게해야합니까? 저를 생략 할 수있는 파이썬 신택스의 장점이 있습니까? 아마도 쉼표 일 수도 있지만 2 번째 val은 없습니까? – mpen

+0

밑줄은 매우 일반적입니다. target_product, _ = Component.object.get_or_create (...) 저는 밑줄을 두 개 사용하며 i18n 기능에 대해 하나의 밑줄을 사용합니다. –

+0

그 밑줄은 꽤 못생긴 것 같지 않니? 그리고 당신이 django i18n을 사용한다면 위험합니다. 플래그를 의미없는 이름으로 지정하면 성능상의 이점이 없습니다. 즉, 원치 않는 변수가 여전히 생성되므로 솔직하게 (그리고 명시 적으로) 의미있는 이름을 지정합니다. – thepeer

4

Django ManyToManyField의 작동 방식은 여분의 테이블을 만드는 것입니다. ModelA와 ModelB의 두 모델이 있다고 가정 해보십시오. id, model_a_id, model_b_id : 당신이 한 경우 ... 장고가 실제로 무대 뒤에서 무엇을

ModelA.model_b = models.ManyToManyField(ModelB) 

는 세 개의 열이있는 테이블 ... app_modela_modelb을 생성합니다.

마음 속에 그 생각을 담아 두십시오. ModelB 저장과 관련하여 Django는 저장 될 때까지 ID를 할당하지 않습니다. 기술적으로 수동으로 ID를 할당하고이 문제를 피할 수 있습니다. 장고가 완벽하게 받아 들일 수있는 것을 처리하게하는 것 같습니다.

장고에는 M2M을 수행하는 데 문제가 있습니다. 왜? ModelB에 아직 ID가없는 경우 M2M 테이블의 model_b_id 열에 무엇이 있습니까? null product_id에 대한 오류는 ModelB 레코드 ID가 아닌 M2M 필드에서 널 (null) 제한 조건 오류 일 가능성이 높습니다.

'함께 성공하기'또는 '함께 실패'하고 싶다면 트랜잭션을 조사해야합니다. 예를 들어 트랜잭션에서 전체를 랩핑하고 부분적으로 실패 할 경우 롤백을 수행합니다. 나는이 분야에서 개인적으로 많은 일을하지 않았으므로 다른 이들이 그 주제에 대한 도움이되기를 바랍니다.

+0

+1 트랜잭션 – Davy8

+0

잘 문서화되어있는 것처럼 보입니다. http://docs.djangoproject.com/en/dev/topics/db/transactions/ – michael

+0

m2m에 대한 해당 주석을 삭제해야합니다. 구성 요소는 * m2m 필드가 아닙니다. 그것은 단지 'ForeignKey'입니다. 이것은 왜 Article이 나오기 전에 Component가 생성 될 수 없는지에 대해서는 정말로 대답하지 않습니다. 내가 이것을 가져 오는 이유는 이것이 형식과 함께 정상적으로 작동하기 때문입니다. 'modelForm.save()'를 실행하면 (자), 프로세스로 필요한 다른 오브젝트가 생성되어 모든 것을 보존합니다 ('commit = False'가없는 한). 어쨌든, 나는'거래'가 괜찮은 대안이라고 생각한다. – mpen

1

잘 이해하려면 the Django documentation을 읽어야하므로 트랜잭션에 코드 스 니펫을 포함시키는 데는 가치가 없습니다.

+0

네가 맞아,하지만 나는 거래를 전혀 포함하지 않는 해결책을 찾고 있었다. 트랜잭션에 관한 문서는 꽤 명확 해 보입니다. – mpen

+0

거래 접근을 피하는 이유는 무엇입니까? –

관련 문제