[ 설문조사 폼 만들기 ]
Survey App 개발 (폼처리,CSRF,redirect등)
1. survey 앱 만들기
python manage.py startapp survey
2. 폴더를 만든다.(survey > templates > survey > list.html)
3. views.py에서 list.html 연결
def home(request):
print("list 모듈 동작!")
return render(request, "survey/list.html")
4. urls.py에 첫페이지 연결
from survey import views
urlpatterns=[
path('',views.home),
]
5. config/settings.py로 가서 survey 등록
6. config/urls.py 가서 path 등록 -> 메인으로 가서 등록
7. models.py에 모델 설정
Survey 모델) 설문조사 문항과 답변 4개, 설문 진행상태(y=진행중 n=종료)
Answer 모델) 응답에 대한 순번과 응답번호
설문조사를 만들어서 그거에 대한 답을 테이블에 저장하는 것
autofield : 자동으로 순번 상승
# 설문조사 문항
class Survey(models.Model):
# 설문 인덱스
survey_idx = models.AutoField(primary_key=True)
# 설문 문제
question = models.TextField(null=True)
# 답 1~4
ans1 = models.TextField(null=True)
ans2 = models.TextField(null=True)
ans3 = models.TextField(null=True)
ans4 = models.TextField(null=True)
# 설문진행상태(y=진행중, n=종료)
status = models.CharField(max_length=1, default="y")
# ------------------------------------------------------------
class Answer(models.Model):
# 응답 아이디(자동필드 증가)
answer_idx = models.AutoField(primary_key=True)
# 설문 아이디
survey_idx = models.IntegerField()
# 응답 번호
num = models.IntegerField()
8. 관리자모드에 survey 등록
admin.py에 surveyAdmin 저장하기
from survey.models import Survey, Answer
class SurveyAdmin(admin.ModelAdmin):
list_display = ("question", "ans1", "ans2", "ans3", "ans4", "status")
admin.site.register(Survey, SurveyAdmin)
admin.site.register(Answer)
9. 모델만들기
적용하기 -> migrations 파일이 만들어짐
python manage.py makemigrations #마이그레이션 만들기
python manage.py migrate #마이그레이션 적용하기
sqlite에 테이블 만들어짐
10. admin에 들어가보자. -> 로컬 호스트로 들어가자
python manage.py runserver
DHCP이기 때문에 새로운 프로젝트를 만들면 새로운 IP가 만들어진다. (불안정한것)
따라서 터미널에서 IP ADDR 해서 ip 추가하자 127.0.0.1 로컬호스트 추가해놓음
survey가 생겼다. / 파일 중 manage.py 생성
survey 추가해주자.
11. views.py 가서 필터 추가
Survey 수입하고 필터로 order by(정렬)하기
from survey.models import Survey
def home(request):
print("list 모듈 동작!")
# filter 조건절에 해당
# [0] 레코드중에서 첫번째 요청
# select * from survey_survey where status='y' => row 10
# 최신 데이터 1개만 추출 / 내림차순 : order by('-xx')[index]
survey = Survey.objects.filter(status='y').order_by('-survey_idx')[0]
return render(request, "survey/list.html", {'survey': survey})
12. list.html 가서 값들 다 출력해보기
잘 나오는지 확인
확인 끝났으니 제대로 써보자.
13. list.html에서 style 추가하기
<style>
#wrap {width:550px; margin:auto}
.sub { background:orange; font-size:30px}
</style>
14. list.html 스타일 적용할 내용 제대로 쓰기
<div id="wrap">
<form method="post" action="save_survey">
{% csrf_token %}
<p class="sub">{{survey.question}}</p>
<p><input type="radio" name="num" value="1" >{{survey.ans1}}</p>
<p><input type="radio" name="num" value="2" >{{survey.ans2}}</p>
<p><input type="radio" name="num" value="3" >{{survey.ans3}}</p>
<p><input type="radio" name="num" value="4" >{{survey.ans4}}</p>
<p>
<input type="hidden" name="survey_idx" value="{{survey.survey_idx}}" >
<input type="submit" value="투표">
<input type="button" value="결과확인" onclick="show_result()">
</p>
</form>
<script>
function show_result(){
location.href= " show_result?survey_idx={{survey.survey_idx}} ";
}
</script>
</div>
autofield는 입력처리를 idx를 생략함(def insert 의 Address부분)
15. views.py에 결과창 연결
save_survey 정의하기
@csrf_protect
def save_survey(request):
# 문제 번호와 응답번호를 Answer 객체에 저장한다.
survey_idx = request.POST["survey_idx"]
print("Type : ", type(survey_idx))
# survey_survey primary key -> 1:n 질문에 대한 답변의 값(survey)
# num :선택한 설문의 항목 번호
dto = Answer(survey_idx=int(request.POST["survey_idx"]), num=request.POST["num"])
# insert query 가 호출
dto.save()
return render(request, "survey/success.html", {'survey_idx': survey_idx})
[ #참고 # 리소스 파일 저장 ]
spring에서는 resource라는 파일에 img를 비롯한 css 파일을 넣어두었다.
우리도 pycharm에 static 이라는 이름의 resource 파일을 만들어서 거기에 img 폴더 안에 이미지를 저장한다.
16. success.html 파일 생성 후 입력
그 이미지를 불러와보자.
# 이미지 불러오기
{% load static %}
{% static "" as baseUrl %}
<head>
<meta charset="UTF-8">
<title>success.html</title>
<style>
#wrap {width:350px; margin:auto; }
#wrap image {width:100px; }
</style>
</head>
<body>
<h2>설문이 완료되었습니다.</h2>
<img src="{{baseUrl}}/img/logo.jpg"><br>
<a href="/survey">투표하기</a> <br>
</body>
</html>
17. urls.py에 path 등록
path('save_survey',views.save_survey),
#17. view에 show_result 정의하기(결과창)
주의) get이다!
@csrf_protect
def show_result(request):
# 문제 번호
idx = request.GET["survey_idx"]
# select * from survey where survey_idx=1 과 같다.
ans = Survey.objects.get(survey_idx=idx)
# 각 문항에 대한 값으로 리스트를 만들어 놓는다.
answer = [ans.ans1, ans.ans2, ans.ans3, ans.ans4]
# Survey.objects.raw("""SQL문""")
surveyList = Survey.objects.raw("""
SELECT survey_idx, num, count(num) sum_num FROM survey_answer
WHERE survey_idx=%s
GROUP BY survey_idx,num
ORDER BY num
""", idx)
surveyList = zip(surveyList, answer)
return render(request, "survey/result.html", {'surveyList': surveyList})
18. urls 에 등록
path('show_result', views.show_result),
19. survey 폴더에 result.html 만들기
설문조사 결과를 출력한다.
view에서 정의한 surveyList의 SQL 문을 가져와서 결과를 띄운다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>result.html</title>
</head>
<body>
<div id="wrap">
<h1>설문조사 결과보기 예제</h1>
<table>
<tr>
<th>문항</th>
<th>응답수</th>
</tr>
<tr>
<td>{{surveyList}}</td>
<td></td>
</tr>
<tr>
<td colspan="2">
<input type="button" value="투표하기" onclick="location='/survey'">
</td>
</tr>
</table>
</div>
</body>
</html>
21. 값 제대로 나오게 바꿔보자
jstl 사용하자. 현재 필요한 결과값들은 응답과 설문한 질문의 갯수들이다.
{% for row, ans in surveyList %}
<tr>
<td>{{ans}}</td>
<td>{{row.sum_num}}</td>
<!--sql에 있는 테이블 row 가져오기-->
</tr>
{%endfor%}
설문을 등록할 수 있는 폼을 만들어보자.
22. 설문 등록폼 write.html 만들기
write.html의 views정의를 write로, DB에 데이터를 입력하는 request.post를 insert로 지정해 줄 것이기 때문에 입력값을 action="insert"로 미리 설정해두었다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>write.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div id="wrap"><h1> write (설문 등록폼) </h1>
<form method="post" action="insert">
<!-- view.py의 save_question 를 정의한 곳으로 이동해서 DB로 보낼 것. -->
{% csrf_token%}
<table>
<tr><td>질문</td><td><input type="text" name="question"></td></tr>
<tr><td>응답1</td><td><input type="text" name="ans1"></td></tr>
<tr><td>응답2</td><td><input type="text" name="ans2"></td></tr>
<tr><td>응답3</td><td><input type="text" name="ans3"></td></tr>
<tr><td>응답4</td><td><input type="text" name="ans4"></td></tr>
<tr><td>상태</td><td><input type="text" name="status"></td></tr>
<tr><input type="submit"></tr>
</table>
</form>
</div>
</body>
</html>
submit 후 insert > DB로 들어갈 것이다.
23. views.py로 가서 write와 insert 정의하기
# write.html 연결
def write(request):
return render(request, "survey/write.html")
# write에 받은거 DB 연동
def insert(request):
# 데이터 베이스에 입력 처리 (idx 는 Oracle의 순번과 동일)
addq = Survey(question=request.POST['question'],
ans1=request.POST['ans1'],
ans2=request.POST['ans2'],
ans3=request.POST['ans3'],
ans4=request.POST['ans4'],
status=request.POST['status'],
)
addq.save()
return redirect("/survey/list")
24. 설문 목록을 볼 수 있는 survey_list.html 만들기
설문 목록창은 설문의 리스트 갯수 출력(survey_count), 내용 출력(table), 설문등록폼으로 이동하기 위한 버튼(location = 'write'), jstl을 이용해 목록 나열 후, 질문 목록에 '상세보기 창 이동 링크'(a태그)를 걸어두었다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>survey_list.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div><h3> survey_list</h3>
<p> 여기는 설문 리스트 : {{survey_count}}</p>
<table>
<thead>
<tr>
<th>번호</th>
<th>질문</th>
<th>응답1</th>
<th>응답2</th>
<th>응답3</th>
<th>응답4</th>
<th>상태</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="5">
<input type="button" value="등록" onclick="location='write'">
</th>
</tr>
</tfoot>
<tbody>
<!--jstl 사용-->
{% for e in items %}
<tr>
<td>{{e.survey_idx}}</td>
<td>
<a href ="------ 입력예정 ------">{{e.question}}</a>
</td>
<td>{{e.ans1}}</td>
<td>{{e.ans2}}</td>
<td>{{e.ans3}}</td>
<td>{{e.ans4}}</td>
<td>{{e.status}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
25. views.py로 가서 list 정의하기
survey를 정렬한 items와 갯수인 survey_count 를 리턴해준다.
#질문목록 정의 / 갯수
def list(request):
items = Survey.objects.order_by('survey_idx')
# group 함수
survey_count = Survey.objects.all().count()
# 이제 이 값을 urls에 넘겨줘야지.
return render(request, "survey/survey_list.html", {'items': items,
'survey_count': survey_count})
26. urls.py에서 path를 지정해준다.
path('list', views.list),
path('write', views.write),
path('insert', views.insert),
27. 설문 상세 페이지인 detail.html 를 만든다.
기본적인 정보를 출력하는 테이블과 리스트, 수정, 삭제로 onclick이 걸린 버튼을 만든다.
추후 script를 설정할꺼니 이름만 정해두자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upform.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div id="wrap">
<h1> survey 수정 </h1>
<form method="post" name="form1">
<!--사이트 위조 방지 설정이 기본적으로 설정 체크-->
{% csrf_token%}
<input type="hidden" name="survey_idx">
<table>
<tr>
<td>질문</td>
<td><input type="text" name="question"></td>
</tr>
<tr>
<td>응답1</td>
<td><input type="text" name="ans1"></td>
</tr>
<tr>
<td>응답2</td>
<td><input type="text" name="ans2"></td>
</tr>
<tr>
<td>응답3</td>
<td><input type="text" name="ans3"></td>
</tr>
<tr>
<td>응답4</td>
<td><input type="text" name="ans4"></td>
</tr>
<tr>
<td>상태</td>
<td><input type="text" name="status"></td>
</tr>
<tr>
<th colspan="2"> <!--버튼 추가-->
<input type="button" value="리스트" onclick="gourl()">
<input type="button" value="수정" onclick="update()">
<input type="button" value="삭제" onclick="del()">
</th>
</tr>
</table>
</form>
</div>
</body>
</html>
28. views.py 에서 detail를 정의한다.
addq는 추가한 설문들이 수정 또는 삭제를 거친 후 최종적으로 정해진 값 idv와 인덱스번호 idx가 같은 경우를 변수로 담는다.
# 상세페이지
def detail(request):
idv = request.GET['survey_idx']
# select * from address_address where idx = idv
addq = Survey.objects.get(survey_idx=idv)
return render(request, 'survey/detail.html', {'addq': addq})
29. survey_list.html에서 상세페이지로 이동하는 a 태그 링크를 걸어준다.
<td>
<a href ="detail?survey_idx={{e.survey_idx}}">{{e.question}}</a>
</td>
30. detail.html에서 survey_idx에 따른 설문 값을 볼 수 있도록 value 값을 설정해준다.
단, 그 값들은 views.py에서 정의한 addq의 조건에 한한다.
<input type="hidden" name="survey_idx" value="{{addq.survey_idx}}">
<table>
<tr>
<td>질문</td>
<td><input type="text" name="question" value="{{addq.question}}"></td>
</tr>
<tr>
<td>응답1</td>
<td><input type="text" name="ans1" value="{{addq.ans1}}"></td>
</tr>
<tr>
<td>응답2</td>
<td><input type="text" name="ans2" value="{{addq.ans2}}"></td>
</tr>
<tr>
<td>응답3</td>
<td><input type="text" name="ans3" value="{{addq.ans3}}"></td>
</tr>
<tr>
<td>응답4</td>
<td><input type="text" name="ans4" value="{{addq.ans4}}"></td>
</tr>
<tr>
<td>상태</td>
<td><input type="text" name="status" value="{{addq.status}}"></td>
</tr>
31. views.py 에서 update와 delete를 정의한다.
삭제와 수정기능에 addq를 변경, 또는 지우는 기능을 부여한다.
# 삭제 기능
# csrf_protect는 csrf 방식을 검증한다.
# 앞으로 post 방식일 때는 반드시 사용을 원칙으로 한다.
@csrf_protect
def delete(request):
idv = request.POST['survey_idx']
print("survey_idx:", idv)
# delete * from address_address where idx = idv
# 선택한 데이터의 레코드가 삭제됨
addq = Survey.objects.get(survey_idx=idv).delete()
return redirect('/survey/list')
# =====================================================
# 수정 기능
@csrf_protect
def update(request):
idv = request.POST['survey_idx']
question = request.POST['question']
ans1 = request.POST['ans1']
ans2 = request.POST['ans2']
ans3 = request.POST['ans3']
ans4 = request.POST['ans4']
status = request.POST['status']
print("survey_idx:", idv)
print("question:", question)
print("ans1:", ans1)
print("ans2:", ans2)
print("ans3:", ans3)
print("ans4:", ans4)
print("status:", status)
# 수정 데이터 베이스 처리(idx=id -> 값을 넣으면 수정, 없으면 auto로 생성되므로 없어도됨)
addq = Survey(survey_idx=idv, question=question, ans1=ans1, ans2=ans2, ans3=ans3, ans4=ans4, status=status)
# 데이터 레코드가 수정됨
addq.save()
return redirect('/survey/list')
32. detail.html에 리스트이동, 수정, 삭제 기능을 위한 script를 추가해준다.
</form>
</div>
<script>
//리스트로 이동
function gourl(){
location="/survey/list"
}
//삭제
function del(){
document.form1.action="delete";
document.form1.submit();
}
//수정
function update(){
document.form1.action="update";
document.form1.submit();
}
</script>
</body>
리스트는 location만 걸면 되고, 삭제, 수정 기능은 view.py에서 지정해둔 기능을 수행한다. "delete"와 "delete"가 def 한 그 기능이다.
정리 ) 뷰에서 수정버튼 누르면 스크립트로 가고 컨트롤러가 요청을 맵핑(url)오고 모델 보고 뷰의 업데이트로 가세요.
33. urls.py에서 path를 지정해준다.
path('detail', views.detail),
path('update', views.update),
path('delete', views.delete),
설정은 다 마쳤다. 이제 원래 우리가 첫페이지로 사용했던 list.html에 survey_list.html로 가는 버튼을 만들어주자.
34. list.html에 질문목록 버튼 생성
<p class="sub">{{survey.question}}</p>
<p><input type="radio" name="num" value="1" >{{survey.ans1}}</p>
<p><input type="radio" name="num" value="2" >{{survey.ans2}}</p>
<p><input type="radio" name="num" value="3" >{{survey.ans3}}</p>
<p><input type="radio" name="num" value="4" >{{survey.ans4}}</p>
<p>
<input type="hidden" name="survey_idx" value="{{survey.survey_idx}}" >
<input type="submit" value="투표">
<input type="button" value="결과확인" onclick="show_result()">
<input type="button" value="질문목록" onclick="location='list'">
</p>
35. 완성 화면
스프링보다 쉽다. 처음부터 끝까지 혼자 해보니 확실히 실력이 느는 느낌 :)
[에러] idx가 올라가면 계속 에러가 난다.
▼ 전체 코드 보기
[전체 코드]
1. detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upform.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div id="wrap">
<h1> survey 수정 </h1>
<form method="post" name="form1">
<!--사이트 위조 방지 설정이 기본적으로 설정 체크-->
{% csrf_token%}
<!--인덱스 번호는 필요 없음
-->
<input type="hidden" name="survey_idx" value="{{addq.survey_idx}}">
<table>
<tr>
<td>질문</td>
<td><input type="text" name="question" value="{{addq.question}}"></td>
</tr>
<tr>
<td>응답1</td>
<td><input type="text" name="ans1" value="{{addq.ans1}}"></td>
</tr>
<tr>
<td>응답2</td>
<td><input type="text" name="ans2" value="{{addq.ans2}}"></td>
</tr>
<tr>
<td>응답3</td>
<td><input type="text" name="ans3" value="{{addq.ans3}}"></td>
</tr>
<tr>
<td>응답4</td>
<td><input type="text" name="ans4" value="{{addq.ans4}}"></td>
</tr>
<tr>
<td>상태</td>
<td><input type="text" name="status" value="{{addq.status}}"></td>
</tr>
<tr>
<th colspan="2"> <!--버튼 추가-->
<input type="button" value="리스트" onclick="gourl()">
<input type="button" value="수정" onclick="update()">
<input type="button" value="삭제" onclick="del()">
</th>
</tr>
</table>
</form>
</div>
<script>
function gourl(){
location="/survey/list"
}
//두 함수의 공통기능을 분석해서 하나의 함수로 변경해보기
function del(){
document.form1.action="delete";
document.form1.submit();
}
function update(){
document.form1.action="update";
document.form1.submit();
}
</script>
</body>
</html>
2. list.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>list.html</title>
<style>
#wrap {width:550px; margin:auto}
.sub { background:orange; font-size:30px}
</style>
</head>
<body>
<div id="wrap">
<form method="post" action="save_survey">
{% csrf_token %}
<p class="sub">{{survey.question}}</p>
<p><input type="radio" name="num" value="1" >{{survey.ans1}}</p>
<p><input type="radio" name="num" value="2" >{{survey.ans2}}</p>
<p><input type="radio" name="num" value="3" >{{survey.ans3}}</p>
<p><input type="radio" name="num" value="4" >{{survey.ans4}}</p>
<p>
<input type="hidden" name="survey_idx" value="{{survey.survey_idx}}" >
<input type="submit" value="투표">
<input type="button" value="결과확인" onclick="show_result()">
<!--===============================================================-->
<input type="button" value="질문목록" onclick="location='list'">
<!--===============================================================-->
</p>
</form>
<script>
function show_result(){
location.href= " show_result?survey_idx={{survey.survey_idx}} ";
}
</script>
</div>
</body>
</html>
3. result.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>result.html</title>
</head>
<body>
<div id="wrap">
<h1>설문조사 결과보기 예제</h1>
<table>
<tr>
<th>문항</th>
<th>응답수</th>
</tr>
{% for row, ans in surveyList %}
<tr>
<td>{{ans}}</td>
<td>{{row.sum_num}}</td>
<!--sql에 있는 테이블 row 가져오기-->
</tr>
{%endfor%}
<tr>
<td colspan="2">
<input type="button" value="투표하기" onclick="location='/survey'">
</td>
</tr>
</table>
</div>
</body>
</html>
4. success.html
<!DOCTYPE html>
<html lang="ko">
# 이미지 불러오기
{% load static %}
{% static "" as baseUrl %}
<head>
<meta charset="UTF-8">
<title>success.html</title>
<style>
#wrap {width:350px; margin:auto; }
#wrap image {width:100px; }
</style>
</head>
<body>
<h2>설문이 완료되었습니다.</h2>
<img src="{{baseUrl}}/img/logo.jpg"><br>
<a href="/survey">투표하기</a> <br>
<a href="show_result?survey_idx={{survey_idx}}">설문조사 결과 보기</a> <br>
</body>
</html>
5. survey_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>survey_list.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div><h3> survey_list</h3>
<p> 여기는 설문 리스트 : {{survey_count}}</p>
<table>
<thead>
<tr>
<th>번호</th>
<th>질문</th>
<th>응답1</th>
<th>응답2</th>
<th>응답3</th>
<th>응답4</th>
<th>상태</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="5">
<input type="button" value="등록" onclick="location='write'">
</th>
</tr>
</tfoot>
<tbody>
<!--jstl 사용-->
{% for e in items %}
<tr>
<td>{{e.survey_idx}}</td>
<td>
<a href ="detail?survey_idx={{e.survey_idx}}">{{e.question}}</a>
</td>
<td>{{e.ans1}}</td>
<td>{{e.ans2}}</td>
<td>{{e.ans3}}</td>
<td>{{e.ans4}}</td>
<td>{{e.status}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
6. write.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>write.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div id="wrap"><h1> write (설문 등록폼) </h1>
<form method="post" action="insert">
<!-- view.py의 save_question 를 정의한 곳으로 이동해서 DB로 보낼 것. -->
{% csrf_token%}
<table>
<tr><td>질문</td><td><input type="text" name="question"></td></tr>
<tr><td>응답1</td><td><input type="text" name="ans1"></td></tr>
<tr><td>응답2</td><td><input type="text" name="ans2"></td></tr>
<tr><td>응답3</td><td><input type="text" name="ans3"></td></tr>
<tr><td>응답4</td><td><input type="text" name="ans4"></td></tr>
<tr><td>상태</td><td><input type="text" name="status"></td></tr>
<tr><input type="submit"></tr>
</table>
</form>
</div>
</body>
</html>
7. models.py
from django.db import models
# Create your models here.
# 설문조사 문항
class Survey(models.Model):
# 설문 인덱스
survey_idx = models.AutoField(primary_key=True)
# 설문 문제
question = models.TextField(null=True)
# 답 1~4
ans1 = models.TextField(null=True)
ans2 = models.TextField(null=True)
ans3 = models.TextField(null=True)
ans4 = models.TextField(null=True)
# 설문진행상태(y=진행중, n=종료)
status = models.CharField(max_length=1, default="y")
# ------------------------------------------------------------
class Answer(models.Model):
# 응답 아이디(자동필드 증가)
answer_idx = models.AutoField(primary_key=True)
# 설문 아이디
survey_idx = models.IntegerField()
# 응답 번호
num = models.IntegerField()
# =============================================================
# 설문 등록
# 위에 survey에 정의되어있음
8. urls.py
from django.urls import path
from survey import views
urlpatterns=[
path('',views.home),
path('save_survey',views.save_survey),
path('show_result', views.show_result),
# ================================================
path('list', views.list),
path('write', views.write),
path('insert', views.insert),
# ================================================
path('detail', views.detail),
path('update', views.update),
path('delete', views.delete),
]
9. views.py
from django.shortcuts import render, redirect
from django.views.decorators.csrf import csrf_protect
from survey.models import Survey, Answer
# Create your views here.
def home(request):
print("list 모듈 동작!")
# filter 조건절에 해당
# [0] 레코드중에서 첫번째 요청
# select * from survey_survey where status='y' => row 10
# 최신 데이터 1개만 추출 / 내림차순 : order by('-xx')[index]
survey = Survey.objects.filter(status='y').order_by('-survey_idx')[0]
return render(request, "survey/list.html", {'survey': survey})
# -------------------------------------------------------------------
@csrf_protect
def save_survey(request):
# 문제 번호와 응답번호를 Answer 객체에 저장한다.
survey_idx = request.POST["survey_idx"]
print("Type : ", type(survey_idx))
# survey_survey primary key -> 1:n 질문에 대한 답변의 값(survey)
# num :선택한 설문의 항목 번호
dto = Answer(survey_idx=int(request.POST["survey_idx"]), num=request.POST["num"])
# insert query 가 호출
dto.save()
return render(request, "survey/success.html", {'survey_idx': survey_idx})
# -------------------------------------------------------------------
@csrf_protect
def show_result(request):
# 문제 번호
idx = request.GET["survey_idx"]
# select * from survey where survey_idx=1 과 같다.
ans = Survey.objects.get(survey_idx=idx)
# 각 문항에 대한 값으로 리스트를 만들어 놓는다.
answer = [ans.ans1, ans.ans2, ans.ans3, ans.ans4]
# Survey.objects.raw("""SQL문""")
surveyList = Survey.objects.raw("""
SELECT survey_idx, num, count(num) sum_num FROM survey_answer
WHERE survey_idx=%s
GROUP BY survey_idx,num
ORDER BY num
""", idx)
# [[ans.ans1, surveyList???
surveyList = zip(surveyList, answer)
return render(request, "survey/result.html", {'surveyList': surveyList})
# ========================================================
# 질문목록 정의 / 갯수
def list(request):
items = Survey.objects.order_by('survey_idx')
# group 함수
survey_count = Survey.objects.all().count()
# 이제 이 값을 urls에 넘겨줘야지.
return render(request, "survey/survey_list.html", {'items': items,
'survey_count': survey_count})
# write.html 연결
def write(request):
return render(request, "survey/write.html")
# write에 받은거 DB 연동
def insert(request):
# 데이터 베이스에 입력 처리 (idx 는 Oracle의 순번과 동일)
addq = Survey(question=request.POST['question'],
ans1=request.POST['ans1'],
ans2=request.POST['ans2'],
ans3=request.POST['ans3'],
ans4=request.POST['ans4'],
status=request.POST['status'],
)
addq.save()
return redirect("/survey/list")
# ========================================================
# 상세페이지
def detail(request):
idv = request.GET['survey_idx']
# select * from address_address where idx = idv
addq = Survey.objects.get(survey_idx=idv)
return render(request, 'survey/detail.html', {'addq': addq})
# 삭제 기능
# csrf_protect는 csrf 방식을 검증한다.
# 앞으로 post 방식일 때는 반드시 사용을 원칙으로 한다.
@csrf_protect
def delete(request):
idv = request.POST['survey_idx']
print("survey_idx:", idv)
# delete * from address_address where idx = idv
# 선택한 데이터의 레코드가 삭제됨
addq = Survey.objects.get(survey_idx=idv).delete()
return redirect('/survey/list')
# 수정 기능
@csrf_protect
def update(request):
idv = request.POST['survey_idx']
question = request.POST['question']
ans1 = request.POST['ans1']
ans2 = request.POST['ans2']
ans3 = request.POST['ans3']
ans4 = request.POST['ans4']
status = request.POST['status']
print("survey_idx:", idv)
print("question:", question)
print("ans1:", ans1)
print("ans2:", ans2)
print("ans3:", ans3)
print("ans4:", ans4)
print("status:", status)
# 수정 데이터 베이스 처리(idx=id -> 값을 넣으면 수정, 없으면 auto로 생성되므로 없어도됨)
addq = Survey(survey_idx=idv, question=question, ans1=ans1, ans2=ans2, ans3=ans3, ans4=ans4, status=status)
# 데이터 레코드가 수정됨
addq.save()
return redirect('/survey/list')
'[ 빅데이터 ]' 카테고리의 다른 글
[빅데이터] 홈페이지 만들기(2) : 파이썬으로 로그인/로그아웃 데모 앱 만들기(오라클 연동) (0) | 2020.10.16 |
---|---|
[빅데이터] Django 오라클 연동 / 홈페이지 만들기(1) : 파이썬으로 회원가입 앱 만들기(아이디 중복확인) (0) | 2020.10.15 |
[ 빅데이터 ] c3js - 분석 결과 시각화하기, 파이차트 출력하기 (0) | 2020.10.14 |
[빅데이터] 리눅스 / 디장고(Django) 오라클 11g 설치, 연동 (0) | 2020.10.14 |
[빅데이터] PyCharm, 디장고(Django) 설치 / 주소록 앱 만들기 (2) | 2020.10.12 |
댓글