http://127.0.0.1:8000/admin/ 접속
- 장고는 개발 편의를 위해 Admin을 제공한다.
계정 생성
- 터미널창에 아래 명령어 실행 후 id password 지정
python manage.py createsuperuser
접속 화면
유저 생성 확인
관리자 페이지에 Question모델 데이터 추가
- admin.py에 코드 추가
from django.contrib import admin
from .models import Question
# Register your models here.
admin.site.register(Question)
- 관리자 페이지에서 Question에 접근할 수 있다.
- 데이터 추가도 직접 가능한 편리한 기능을 장고에서는 제공한다.
질문 상세 기능 구현하기
vies.py 파일의 index 함수 변경
- 아래와 같은 렌더링 과정을 통해 코드가 아닌 우리가 작성한 HTML 파일을 연결해 줄 수 있다.
def index(request):
question_list = Question.objects.order_by('-create_date') # 내림차순으로 정렬하기 위해 - 붙임
context = {"question_list":question_list}
return render(request, 'pybo/question_list.html',context)
폴더관리
- Spring의 경우 html을 모아두는 temlplate 디렉터리와 js, css 파일을 모아두는 static 디렉터리가 존재한다.
- 장고 또한 이러한 디렉터리를 연동해 주기 위해 설정이 존재한다.
- setting.py의 Templates의 DIRS를 아래 그림과 같이 수정해 준다.
- BASE_DIR 은 mysite 폴더이다
- 그렇기 때문에 위 설정과 같은 DIR 경로가 지정되기 위해서 mysite 아래에 templates 디렉터리를 생성해줘야 한다.
- Templates 경로는 c:\chang_git\mysite\templates이다.
- 위 views.py의 index함수에서 렌더링 경로를 'pybo\question_list.html'로 지정했다 -> 'pybo/' 경로를 직접 생성하는 과정이 필요하다.
- 그러면 'pybo/question_list.html'이 아니라 'question_list.html이 렌더링 경로로 설정되면 되는 거 아니냐? 싶지만
- 브라우저에서 접속 시에 www.naver.com/blog처럼 나오게 하기 위해서 아래처럼 파일경로를 생성하여 만든다.
- 그 후 해당 디렉터리를 templates로 인식할 수 있도록 명시해 주는 설정이 필요하다.
- Templates와 그 하위 폴더인 pybo 폴더 모두 templates로 설정해 준다.
question_list.html 파일
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
</head>
<body>
{% if question_list %}
<ul>
{% for question in question_list %}
<li><a href="/pybo/{{ question.id}}">{{question.subject}}</a></li>
{% endfor %}
</ul>
{% else %}
<p>질문이 없습니다.</p>
{% endif %}
</body>
</html>
127.0.0.1:8000/pybo/에 접속한 결과
게시글 제목의 a 태그 href 속성에 해당하는 동적 URL 매핑
1. path 설정
- pydo의 urls 파일로 이동하여 아래 path 추가
path("<int:question_id>",views.detail)
2. views.py에 path에 연결해 둔 렌더링 함수 작성.
def detail(request, question_id):
question = Question.objects.get(id=question_id)
context = {'question' : question}
return render(request,'pybo/question_detail.html',context)
3. question_detail HTML 파일 작성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ question.subject }}</h1>
<div>{{ question.content }}</div>
</body>
</html>
- 127.0.0.1:8000/pybo에서 클릭할 경우 위 페이지로 이동한다.
만약 웹 브라우저에서 존재하지 않는 ID로의 접근한다면 어떻게 될까?
EX) 127.0.0.1:8000/pybo/10 실행 결과
- 에러의 경우 찾지 못한 에러이기 때문에 404 에러가 출력되는 것이 정상적이다.
- 그렇기 때문에 views.py의 detail을 불러올 때 추가적인 예외처리를 해주는 get_object_or_404 함수를 사용해 준다.
from django.shortcuts import render ,get_object_or_404
def detail(request, question_id):
#question = Question.objects.get(id=question_id) # 그냥 받을 때
question = get_object_or_404(Question, pk = question_id)#에러 처리 할때
context = {'question' : question}
return render(request,'pybo/question_detail.html',context)
변경된 에러
path의 경우 name 옵션으로 별칭 지정이 가능하다.
수정된 path
app_name = 'pybo'
**path("<int:question_id**>",views.detail, name = "detail") # name 옵션으로 별칭 지정이 가능하다.
수정된 question_list.html 파일
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='UTF-8'>
</head>
<body>
{% if question_list %}
<ul>
{% for question in question_list %}
<!--<li><a href="/pybo/{{ question.id}}">{{question.subject}}</a></li> 원래 코드-->
<li><a href = "{% url 'pybo:detail' question.id %}">{{ question.subject }}</a></li><!-- 별칭 수정한 코드-->
{% endfor %}
</ul>
{% else %}
<p>질문이 없습니다.</p>
{% endif %}
만약 다른 디렉토리 내에 같은 별칭이 있다면?
- html href 속성 값으로 url ‘detail’로 전달한다면 동일한 별칭 중 어느 것을 찾아가야 할지 알 수 없다.
- 그렇기 때문에 urls 파일에 app_name = ‘pybo’와 같이 설정해주고,
- url ‘pybo:detail’로 지정해 줘야 찾아갈 수 없다.
답변 상세 기능 구현하기
- 질문을 클릭할 경우 해당 글로 들어가는 것까지는 구현이 되었다.
- 다음으로 질문별로 답변을 남길 수 있는 Answer를 입력해 주는 공간이 필요하다.
1. path 설정
- 답변 등록에 대한 URL 매핑이 필요함
path("answer/create/<int:question_id>",views.answer_create, name = "answer_create")
2. views.py 추가
- answer_create 가 path로 설정되어 있기 때문에 ansswer_create 함수가 필요하다.
- 아까 쉘에서 데이터베이스 데이터를 입력했던 방식으로 a에 저장하여 save 하는 방법도 있고, 아래와 같은 방법도 있다.
def answer_create(request, question_id):
question = get_object_or_404(Question,pk = question_id)
request.POST.get("content")
# save() 랑 동일한 기능이고 create안에 들어가는 값이 만들어지는 값임
question.answer_set.create(content = request.POST.get("content") , create_date= timezone.now())
return redirect("pybo:detail", question_id = question_id)
3.question_detail HTML 파일 수정
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ question.subject }}</h1>
<div>{{ question.content }}</div>
<hr>
<h5>{{ question.answer_set.count }}개의 답변이 있습니다.</h5>
<div>
<ul>
{% for answer in question.answer_set.all %}
<li>{{ answer.content }}</li>
{% endfor %}
</ul>
</div>
<hr>
<form action="{% url 'pybo:answer_create' question.id %}" method="post">
{% csrf_token %} <!-- CSRF 공격을 막기 위해 명시적으로 넣어줘야 실행됨.-->
<textarea name="content" id="content" cols="30" rows="10"></textarea>
<input type="submit" value = "답변등록">
</form>
</body>
</html>
- 데이터베이스에도 데이터가 저장됨을 볼 수 있다
'Back > Django' 카테고리의 다른 글
4. 게시판 페이징 기능 추가하기 (0) | 2023.04.19 |
---|---|
3.5 Django 흐름 정리 (0) | 2023.04.19 |
3. 장고 부트스트랩으로 화면 꾸미기 (0) | 2023.04.19 |
1. 장고의 기본 요소 Url, Database 연동, ORM (0) | 2023.04.13 |
0. 장고 개발 준비 (0) | 2023.04.12 |