Django Foreign Key
하… 정말 생각지도 못한 일로 2시간을 고통받고 글을 쓴다.
공식 문서에 Foreign Key에 대한 문서가 잘 되어있었기에 확실히 해결할 수 있었던 문제다.
결론부터 말하자면, Foreign Key는 기본으로 CASCADE정책을 사용한다!!!
문제 설명
class DatePost(models.Model):
couple = models.ForeignKey(Couple, related_name='dataposts')
title = models.CharField(max_length=100)
message = models.CharField(max_length=1000)
tags = ArrayField(models.CharField(max_length=30), db_index=True)
커플은 데이트를 한다.
데이트를 하고 데이트포스트를 남긴다.
문제는 DatePost를 삭제했더니, Couple까지 사라진다(…???)
이쯤에서 눈치챘어야 하지만… DRF를 쓰는 나는 의심할게 너무 많았다.
특히 Serializer에 read_only=True
까지 넣어둔 상황이라 더 그랬다.
살펴본 것은 순서대로 아래와 같다:
- Serializer 가장 Model과 찰싹 붙어있는 녀석이므로 의심했으나, 아무 문제 없었다.
- ModelViewSet 혹시 이녀석이 문제를 일으키나 했는데, 단순히 Model의 delete()를 부르는 일을 할 뿐이었다.
- Model 흘겨봤으나 별 문제를 찾지 못했다.
- Model Collector 여기서 찾았다… 여기서 실제로 생성되는 SQL을 볼 수 있기 때문이었다..
4의 결과로 알아낸 것은, 자동 생성된 SQL이 꽤나 비효율적이라는 것과, 내 Couple을 DELETE 2차 쿼리에서 삭제한다는 것이었다.
문제 해결
결국,
couple = models.ForeignKey(Couple, on_delete=models.SET_NULL, null=True, related_name='dataposts')
로 코드를 수정하고 나서 나는 광명을 되찾았다.
이 참에 자주 사용될 on_delete옵션을 정리했다.
- CASCADE 같이 죽어버린다…
- SET_NULL null로 값을 바꿔놓는다. 단 null=True로 선언되어 있어야 한다.
- SET_DEFAULT default value로 값을 바꿔놓는다.
- SET(value) value로 값을 설정한다. value로는 함수(callable)를 보낼 수도 있다.
Django 1.9부터는 on_delete가 필수 매개변수가 된다고 한다.
Django 2.0부터는 on_delete가 kwargs에서 두번째 매개변수로 강제된다고 한다.
'WebDev' 카테고리의 다른 글
AWS (0) | 2016.03.02 |
---|---|
letsencrypt (0) | 2016.02.29 |
Require.js (0) | 2016.02.20 |
tosync.js (0) | 2016.02.20 |
Chrome extension 개발 (0) | 2016.02.16 |