장고걸스 완료하고 점프투장고 고고
장고걸스에서 다루지 않았던 내용들만 정리하려한다.
Question
이라는 모델이 있다고 하자.
Question.objects.all()
을 실행하면
위와 같이 뜨는데 (1), (2) 는 장고가 자동 생성해준 Id이다.
이를 사람이 보기 편하게 하기 위해서는 models.py 파일의 Question
클래스에 아래 코드를 추가해주면 아래 사진과 같이 id가 아닌 제목을 표시해준다.
def __str__(self):
return self.subject
<주의할 점>
makemigrations
, migrate
명령은 모델의 속성이 추가되거나 변경된 경우에 실행해야 하는 명령
메서드가 추가 시에는 X
filter
, get
을 사용할 수 있다.
Question.objects.filter(조건)
: 1개 이상의 데이터를 리스트 형태로 반환Question.objects.get(조건)
: 1개의 데이터를 조회 삭제, 수정은 추후에 다룰 때 추가
모델들을 장고 Admin에 등록하면 모델을 쉽게 관리할 수 있다.
admin.py
에 아래 코드를 추가한다.
from .models import Question
admin.site.register(Question)
(Question은 모델 이름)
admin.py
에 아래 코드를 추가한다.
(QuestionAdmin
은 모델이름+Admin, search_fields
에는 검색을 원하는 속성을 적어준다.)
class QuestionAdmin(admin.ModelAdmin):
search_fields = ['subject']
admin.site.register(Question, QuestionAdmin)
모델을 등록할 때 쳤던 코드에 QuestionAdmin
을 추가한다.
그럼 관리자페이지에 이렇게 검색창이 생긴다.
템플릿에서 <li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li>
라고 쓰면 주소 형식이 바뀔 때마다 모든 href
의 형식을 바꿔줘야 한다.
이런 비효율을 없애기 위해 URL 별칭을 이용한다.
pybo/urls.py
파일을 수정. path 함수에 있는 URL 매핑에 name 속성을 부여pybo/urls.py
는 앱 내 urls.py)path('<int:question_id>/', views.detail, name='detail'),
위와 같이 detail 이라는 별칭을 지어주자
question_list.html
템플릿 수정"/pybo/{{ question.id }}/"
부분을 "{% url 'detail' question.id %}"
로 바꿔준다. 변경 전 : <li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li>
변경 후: <li><a href="{% url 'detail' question.id %}">{{ question.subject }}</a></li>
서로 다른 앱에서 같은 URL 별칭을 사용하면 중복 문제가 발생한다.
이런 문제를 없애기 위해 URL 네임 스페이스를 사용한다.
pybo/urls.py
파일을 수정.
urlpatterns
위쪽에 아래 코드를 넣어준다.
app_name = 'pybo'
pybo/question_list.html
수정하기
변경 전 : {% url 'detail' question.id %}
변경 후 : {% url 'pybo:detail' question.id %}
pybo/question_detail.html
파일에 아래 코드를 추가한다.
<form action="{% url 'pybo:answer_create' question.id %}" method="post">
{% csrf_token %}
<textarea name="content" id="content" rows="15"></textarea>
<input type="submit" value="답변등록">
</form>
{% csrf_token %}
: form 엘리먼트를 통해 전송된 데이터(답변)가 실제로 웹 브라우저에서 작성된 데이터인지 판단하는 검사기 역할 태그 바로 밑에 항상 입력해야 함pybo/urls.py
파일에 아래 코드를 추가한다.
path('answer/create/<int:question_id>/', views.answer_create, name='answer_create'),
form 엘리먼트에 입력된 값을 받아 데이터베이스에 저장할 수 있도록 pybo/views.py
파일에 answer_create
함수를 추가한다.
def answer_create(request, question_id):
question = get_object_or_404(Question, pk=question_id)
question.answer_set.create(content=request.POST.get('content'), create_date=timezone.now())
request.POST.get('content')
: request 매개변수에는 question_detail.html에서 textarea에 입력된 데이터가 담겨 넘어옴. 이 값을 추출하기 위한 코드.question.answer_set.create
: Question 모델을 통해 Answer 모델 데이터를 생성 pybo/views.py
파일에 아래 코드 추가한다.
return redirect('pybo:detail', question_id=question.id)
redirect
함수 : 함수에 전달된 값을 참고하여 페이지 이동을 수행.pybo/question_detail.html
파일을 수정한다.
div 태그와 form 태그 사이에 아래 코드를 추가한다.
<h5>{{ question.answer_set.count }}개의 답변이 있습니다.</h5>
<div>
<ul>
{% for answer in question.answer_set.all %}
<li>{{ answer.content }}</li>
{% endfor %}
</ul>
</div>
성공하면 아래와 같이 질문, 답변이 뜬다.