본문 바로가기

데브코스/TIL

[TIL] 4주차_Day12: Django 프레임워크를 사용해서 API서버 만들기(2)

💡Today I Learned

  • 파이썬 장고 프레임워크를 이용한 API 서버 만들기의 두 번째 강의를 진행했습니다.
  • django views, template, detail page, 에러처리, 장고 어드민 페이지의 커스터마이징에 대한 이론 및 실습

 


 

1. 뷰(Views)와 템플릿(Templates)

: models = DB의 정보를 저장, 읽어옴

 

: views = model의 정보(=DB의 정보)를 활용

 

: templates = HTML을 이용해 데이터를 표시해주기위함, [앱 이름]/templates/[앱 이름]/~~~.html

 

: render() = Django의 내장 함수, HTTP 요청에 대해 템플릿 파일을 렌더링해 응답함 (보통 Django의 뷰(View)에서 사용)

: render(요청(Request) 객체, 템플릿 파일 경로, Context 변수)

 

a. 정렬 (order_by): 속성명 앞에 '-' 붙이면 내림차순 정렬

Question.objects.order_by('-pub_date')[:5]

 

b. templates 이용해 html을 화면에 그려주기 위한 'render' 가져오기

from django.shortcuts import render

 

2. 템플릿에서 제어문 사용하기

: {% 제어문 %}

: {{변수명}}

 

a. 반복문

{% for question in questions %}
<li>{{question}}</li>
{% endfor %}

 

b. 조건문

{% if questions %}

{% else %}

{% endif %}

 

3. 상세(detail) 페이지

: url에 특정 question_id가 들어왔을 때 상세 페이지로 이동하기

 

*) 주의할 점: .html 템플릿 파일의 제어문 내에서는 question.choice_set.all() 괄호 적지 않기!

 

4. 상세 페이지로 링크 추가하기

: 링크 → <a href=""><a/> 태그 이용!

 

a. 변수 이용해 url 직접 지정

<li><a href="/polls/{{question.id}}">{{question.question_text}}</a></li>

 

b. 앱의 urls.py 내에서 지정한 [app_name]:[path_name] 이용해 코드로 구현

<li><a href="{% url 'polls:question_detail' question.id %}">{{question.question_text}}</a></li>

: 이동할 링크 = {% 태그 '[app_name]:[path에서 지정한 name]' 입력 파라미터 %}

 

5. 404 에러 처리

: 404 error = 잘못된 요청 (없는 페이지)

: .get()은 찾지 못했을 때 'DoesNotExist' 에러를 발생시킴

 

a. try except문 + Http404 이용

from django.shortcuts import get_object_or_404
question = get_object_or_404(Question, pk=question_id)
context = {'question': question}
 
return render(request, 'polls/detail.html', context)

: pk = primary key (기본키)

 

b. (shortcut) django.shortcuts.get_object_or_404 이용

from django.http import Http404
try:
    question = Question.objects.get(pk=question_id)
    context = {'question': question}

except Question.DoesNotExist:
    raise Http404("Question does not exist")
 
return render(request, 'polls/detail.html', context)

 

6. 폼(forms)

: question을 클릭했을 때의 상세 페이지를 form으로 구성

 

a. 사용자 input 받기 ('radio' type)

<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">

: {{ forloop.counter }} = for문이 돌 때마다 1, 2, 3, .. counting 되면서 값이 바뀜

: question에 딸린 choice 개수만큼 input을 생성

 

b. CSRF_token 설정: form을 제출할 token을 설정 (서버에서 그려준 form에서만 값을 제출할 수 있도록 방어해줌)

{% csrf_token %}

: 장고에서 자동으로 만들어둔 토큰, 장고가 '허락한 form에서 값이 전달됐구나' 하고 허용해줌

 

c. 제출된 form에 대한 처리

: 이동할 page의 path 추가(urls.py)  vote 함수 구현(views.py) & detail.html에서 이동된 page의 화면 출력 구성

 

 

7. 에러 방어하기(1)

: 1) 선택하지 않은 경우  KeyError 발생

: 2) '없는 선택지'를 선택한 경우  DoseNotExist 발생

: 2) → 선택 반영하기 전 해당 옵션(즉, Choice object)이 사라졌을 경우 or 브라우저에서 어떤 에러가 발생해 존재하지 않는 엉뚱한 choice_id 값이 전달되는 경우.. 등을 대비

 

*) 주의할 점: 에러 방어에는 추후 발생할 상황에 대해서도 미리 대비해야되겠구나..!

 

8. 에러 방어하기(2)

: ex) 두 사람이 동시에 같은 form 제출(같은 내용을 vote) + 서로 다른 django server(A, B) 에 접속 + 모두 같은 DB에 연결

: A 서버   votes==0 에서 +1 증가 / B 서버  → votes==0 에서 +1 증가

: 따라서 'selected_choice.votes += 1' 의 연산을 서버가 아닌 DB에서 수행하도록 해줌, 동시에 실행한 명령이 DB에서는 동시에 실행되지 않을 것

 

a. 수정 전: 서버에서 연산

selected_choice.votes += 1

 

b. 수정 후: DB에서 연산

from django.db.models import F
selected_choice.votes = F('votes') + 1 # F('col'): DB에서 col 값을 읽어와라

 

9. 결과(Result) 조회 페이지

: vote 후(form 제출)의 결과를 조회

: result 페이지로 redirect 시 'question_id' 라는 값을 함께 전달해야 함 → reverse( [redirect할 app_name:path name], args=(전달할 값,) )

 

*) 함수 가변길이 param

: *args - 입력 파라미터 개수 유동적

: **kwargs - 입력 파라미터 개수 유동적 & key:value pair로 받음

 

10. 장고 어드민의 편집 페이지 Customizing

: 장고 어드민에서는 model 만들고 추가 시 모델 내용에 대한 CRUD 가능한 페이지 만들 수 있음

: CRUD(Create Read Update Delete)

: admin.ModelAdmin을 상속받은 class 생성 → 모델모델어드민 클래스를 admin.size.register()로 함께 등록!

: fieldsets 정의 (모델 페이지에서 보여질 필드)

: readonly_fields = 수정x 읽기 전용 필드

 

11. 장고 어드민의 목록 페이지 Customizing

: Question 어드민 페이지에서 표시하고싶은 필드, 메소드 ... 지정해주기

: Question 모델에서 필드 정의 시 'verbose_name' 으로 페이지에 표시될 필드의 이름 지정해주기

: Question object 검색하기 1) pub_date(DateTimeField) 기준  2) 'question_text', 'choice__choice_text' (CharField) 기준 → 장고에서 Field 타입에 맞는 filtering 옵션 제공해줌

: @admin.display 데코레이터는 모델 필드가 표시되는 방식을 사용자가 지정할 수 있도록 하는 기능을 제공

반응형