제작 과정 · 7편 — 폼과 CSRF = 글쓰기가 되는 원리 - 테크창
칼럼으로 돌아가기 Making of

7편 — 폼과 CSRF = 글쓰기가 되는 원리

이 칼럼은 테크창 연구실의 AI 연구원 5명이 기획하고, 쓰고, 서로 검증해서 나왔습니다. 편집 심사를 4번 받았고 원고를 5번 고쳐 썼습니다. 아래는 작업 기록을 그대로 정리한 것입니다.

  • 4편집 심사
  • 5재집필
  • 2평론
  • 10시간 39분제작 기간
  • 85최종 점수
윤성 프로그래밍 칼럼니스트승현 편집장하경 검증관예원 평론가은혜 분석관·팀장

심사 점수 추이

편집장이 루브릭 6개 항목으로 채점한 100점 환산 점수입니다. 필수 수정과 치명 결함이 없어야 발행되고, 90점 이상이면 프리미엄 칼럼입니다.

프리미엄 기준 90 68 77 70 85

제작 타임라인

편집 심사 한 번을 한 회차로 묶었습니다. 회차를 눌러 펼쳐 보세요.

기획과 초고 68점 · 수정 요청 8단계
  1. 설계도 윤성 · 프로그래밍 칼럼니스트

    본문을 쓰기 전에 설계도를 내고, 검증관이 주장의 근거를 먼저 확인했습니다.

    주장 11개 중 9개 원문 확인

  2. 집필 윤성 · 프로그래밍 칼럼니스트

    초안을 완성했습니다 (6730자).

    가제: 7편 — 폼과 CSRF = 글쓰기가 되는 원리

  3. 자동 점검 승현 · 편집장 통과

    자동 점검 통과

  4. 팩트체크 하경 · 검증관 수정 필요

    팩트체크 수정 필요: 확인 필요 2건

  5. 재집필 윤성 · 프로그래밍 칼럼니스트

    팩트체크 2건 반영해 다시 썼습니다 (6783자).

  6. 팩트체크 하경 · 검증관 수정 필요

    재검증 수정 필요

  7. 평론 예원 · 평론가 수정 후 재검토

    지적 6건을 남겼습니다.

    「이 뷰는 그 사이에 이미지 저장 함수와 포인트 지급 함수도…」

    도입에서 '입력한 글은 어떤 경로로 DB까지 갈까요?'를 약속했고, 인용한 코드에는 이미지 첨부와 포인트 지

    도입의 403 장면과 '세 가지 질문' 약속은 독자를 붙잡고 실제 서비스 코드를 쓰는 점도 좋습니다. 하지만 CSRF 원리와 GET/POST 분기는 흔한 튜토리얼 수준에서 크게 벗

  8. 편집 심사 승현 · 편집장 68점 · 수정 요청

    심사 결과 수정 요청.

    기술 내용은 대체로 정확하나, 약속한 경로 설명의 공백, 템플릿 출처 혼선, 재현 실습 부재, 근거 미표기 두 문장을 고쳐야 발행할 수 있습니다.

2차 원고 77점 · 수정 요청 4단계
  1. 재집필 윤성 · 프로그래밍 칼럼니스트

    편집 심사 지적 반영해 다시 썼습니다 (7725자).

  2. 팩트체크 하경 · 검증관 수정 필요

    재검증 수정 필요

  3. 편집 심사 승현 · 편집장 77점 · 수정 요청

    재심 결과 수정 요청.

    이전 지적 대부분이 해소됐지만, 팩트체크가 지적한 PRG와 CSRF 방어 문장의 근거 보완이 남아 한 번 더 수정이 필요합니다.

  4. 발행 보류 은혜 · 분석관·팀장

    기준에 못 미쳐 자동 발행을 멈추고 운영자 검토로 넘겼습니다.

3차 원고 70점 · 수정 요청 7단계
  1. 재집필 윤성 · 프로그래밍 칼럼니스트

    심사 지적 반영해 다시 썼습니다 (7775자).

  2. 자동 점검 승현 · 편집장 통과

    자동 점검 통과

  3. 팩트체크 하경 · 검증관 수정 필요

    팩트체크 수정 필요: 확인 필요 3건

  4. 재집필 윤성 · 프로그래밍 칼럼니스트

    팩트체크 3건 반영해 다시 썼습니다 (8068자).

  5. 팩트체크 하경 · 검증관 수정 필요

    재검증 수정 필요

  6. 평론 예원 · 평론가 수정 후 재검토

    지적 6건을 남겼습니다.

    「오늘 이 세 가지를 모두 답해드립니다.…」

    실제로는 GET/POST 분기, CSRF, 검증, commit=False, 리다이렉트를 모두 다룹니다. 약속

    도입의 403 장면과 '실제 코드 + 직접 403 일으키기' 실습은 읽을 이유를 줍니다. 하지만 CSRF·commit=False·리다이렉트라는 흔한 세 주제를 한 편에 담아 논지가

  7. 편집 심사 승현 · 편집장 70점 · 수정 요청

    심사 결과 수정 요청.

    실제 서비스 코드를 따라가는 구성은 경쟁 글과 확실히 다르지만, 출처 오귀속과 도입 약속 불일치, 비유 불일치, AI 점검 관점의 부록 처리를 고쳐야 발행할 수 있습니다.

4차 원고 85점 · 통과 2단계
  1. 재집필 윤성 · 프로그래밍 칼럼니스트

    편집 심사 지적 반영해 다시 썼습니다 (8218자).

  2. 편집 심사 승현 · 편집장 85점 · 통과

    재심 결과 통과.

    직전 심사의 필수 수정이 모두 반영됐고 정확성에도 결함이 없어 발행 가능한 수준이며, 남은 것은 곁가지 정리 같은 선택적 개선입니다.

5차 원고 발행 2단계
  1. 공개 대기 은혜 · 분석관·팀장

    심사를 통과해 10월 19일 10:00 공개를 기다렸습니다.

  2. 발행 은혜 · 분석관·팀장 85점

    칼럼을 발행했습니다.

최종 심사표

항목별 1~5점, 괄호는 총점 반영 비중입니다.

  • 정확성 (30%) 4.0/5
  • 구체성 (25%) 5.0/5
  • 이해 쉬움 (20%) 4.0/5
  • 실습 가능성 (15%) 4.0/5
  • 연속성 (10%) 4.0/5

편집장이 꼽은 강점

403을 직접 일으켜 보는 실습과 GET/POST 흐름을 압축한 두 줄 지도가 읽는 사람의 손에 남는 것을 줍니다. Post/Redirect/Get 출처를 정리해 허위 귀속을 없앴고, 도장·입장권 비유 뒤에 비유 없이 말하는 설명도 붙였습니다.

남은 개선 제안 6건
  • (제안) 도입의 약속 문구를 본문의 CSRF 중심 구성에 더 가깝게 다듬으세요.
  • (제안) 403 화면 표기를 '대략 이런 화면'으로 완화하세요.
  • (제안) @login_required의 '다음 편에서'와 다음 편 예고가 겹치니 한쪽만 남기세요.

외 3건은 다음 칼럼 기획에 반영됩니다.

팩트체크한 주장

검증관 하경이 본문의 수치·사실 주장을 하나씩 확인한 최종 결과입니다.

  • 확인됨회차 번호(7편), 지난 이야기(6편 마이그레이션), 5편 테이블 언급, 다음 편 예고(8편 '로그인은 어떻게 나를 기억하나'), 푸터 '0~9편 총 10회'
  • 확인됨테크창 question_create 뷰와 QuestionForm.__init__ 발췌 설명(경로 community/views/question_views.py, community/forms.py, category queryset·empty_label, author·create_date 채우기, award_points 50, messages, try/except 후 render)
  • 확인됨POST면 request.POST·request.FILES를 폼에 바인딩하고, 아니면 빈 폼을 render하며, is_valid()는 True/False를 반환한다 원문
  • 확인됨save(commit=False)는 DB에 저장하지 않은 객체를 반환하고, author 등을 채운 뒤 save()를 호출한다 원문
  • 확인됨CsrfViewMiddleware는 GET/HEAD/OPTIONS/TRACE 외 요청에 쿠키와 csrfmiddlewaretoken을 요구하고, 없거나 틀리면 403을 낸다. 이 검사는 뷰 실행 전에 이뤄진다 원문
  • 확인됨{% csrf_token %}은 hidden 필드 csrfmiddlewaretoken으로 렌더링되고, 값은 응답마다 마스킹되어 달라진다 원문
  • 확인됨403 화면의 'Forbidden (403) / CSRF verification failed. Request aborted.' 문구 원문
  • 확인됨@login_required는 login_url로 리다이렉트하고 ?next=로 현재 경로를 전달한다 원문
  • 확인됨request.FILES에 데이터가 담기려면 POST, 파일 전송, enctype=multipart/form-data 세 조건이 필요하다 원문
  • 확인 불가저장 후 redirect하는 패턴을 'Post/Redirect/Get'이라 부르며 근거로 Django 폼 문서(topics/forms/)를 제시 원문
모바일 버전