11. Ajax

12. Ajax + DB

13. Join

 


11. Ajax

 : ajax 송부한 데이터에 문자열 더하여 수신 받기.

 : ajax 요청하여 수신 받은 데이터 출력하기.

 

 = django_test10_ajax

 * settings

INSTALLED_APPS = [
    
    ...
    
    'myajaxapp',
]

 => application 연결

 

 * urls

from django.contrib import admin
from django.urls import path
from myajaxapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.indexFunc),
    path('startajax', views.func1),
    path('goajax', views.func2),
]

 => url -> function 연결

     url '' -> indexFunc

     url 'startajax' -> func1

     url 'goajax' -> func2

 

 

 * views

from django.shortcuts import render
import json
from django.http.response import HttpResponse

lan = {
    'id':111,
    'name':'파이썬',
    'history':[
        {'date':'2021-2-12','exam':'basic'},
        {'date':'2021-2-22','exam':'django'},
    ]
}

def test(): # json encoding/decoding
    print(type(lan)) # dict
    jsonString  = json.dumps(lan)
    jsonString  = json.dumps(lan, indent = 4) # 들어쓰기
    print(jsonString)
    #{"id": 111, "name": "\ud30c\uc774\uc36c", 
    #"history": [{"date": "2021-2-12", "exam": "basic"}, {"date": "2021-2-22", "exam": "django"}]}
    print(type(jsonString)) # str
    
    print('----------------------------------------------------------')
    
    dic = json.loads(jsonString)
    print(dic)
    print(type(dic)) # dict
    print(dic['name'])
    for h in dic['history']:
        print(h['date'], h['exam'])
    #2021-2-12 basic
    #2021-2-22 django
    
def indexFunc(request):
    test()
    return render(request,'abc.html')
	
    ...

 => import jason

 => json.dumps(data, indent = 들여쓰기) : json encoding. python object(Dict, List, Tuple..)를 문자열로 변경하는 작업

 => json.loads(data) : json decoding. 문자열을 python object(Dict, List, Tuple..)로 변경하는 작업

 => indexFunc() -> abc.html

 

 * abc.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	$("#btn1").click(function(){
		let msg = $("#txtMsg").val()
		$("#showData").empty();
		$.ajax({
			url:'startajax',
			type:'get',
			data:{'msg':msg}, /* msg=msg */
			dataType:'json',
			success:function(data){
				let str = '';
				for(let k in data){
					let str = k + '<br>' + data[k];
				}
				str += "<br><b>"+data['key']+"</b>";
				$("#showData").html(str);
			},
			error:function(){
				$("#showData").text("에러");
			}
		});
	});
	
	$("#btn2").click(function(){
		//$("#showData2").text("<i>1</i>"); // <i> 그대로 출력
		$("#showData2").html("<i>1</i>");
		$.ajax({
			url:'goajax',
			type:'get',
			dataType:'json',
			success:function(data){
				//alert(data);
				let str = '';
				$.each(data, function(ind, entry){ //jquery 반복문
					str += entry['name'] + ', ' + entry['age'] + '<br>';
				});
				$("#showData2").html(str);
			},
			error:function(){
				$("#showData2").text("에러");
			}
		});
	});
});
</script>
</head>
<body>
<h2>Ajax test</h2>
자료입력 : <input type="text" id="txtMsg" value="홍길동">
<button id="btn1">버튼1 클릭</button>
<br>
<div id="showData">실습결과1</div>
<hr>
<button id="btn2">버튼2 클릭</button>
<br>
<div id="showData2">실습결과2</div>
</body>
</html>

$.ajax({

    url:'요청명',

    type:'get/post',

    dataType:'json',

    success:function(x){

        // 성공 시 실행문

    }

    error:function(){

        // 에러 발생 시 실행문

    }

});

=> ajax 처리

 

$.each(x, function(idx, entry){

    // for entry in x: 과 동일

    // 반복문

});

 => json 반복문

 * views

...

import time
def func1(request):
    msg = request.GET['msg']
    #print(msg) # 홍길동
    time.sleep(1);
    context = {'key':msg + ' ajax 요청 처리'} # dict - 홍길동 ajax 요청 처리
    return HttpResponse(json.dumps(context), content_type="application/json") # dict -> str

def func2(request):
    datas = [
        {'name' : '고길동', 'age':25},
        {'name' : '김길동', 'age':27},
        {'name' : '나길동', 'age':28},
    ]
    return HttpResponse(json.dumps(datas), content_type="application/json")

 => request.GET['msg'] : 요청의 'msg' key의 값을 get.

 => HttpResponse(json.dumps(context), content_type="application/json") : context를 dict 타입에서 str로 변환 후

       json형식의 str을 send.


12. Ajax + DB

 : ajax 요청 시 DB의 직원 테이블 data 조회하여 출력하기.

 

 = django_test11_ajax

 => create application - myajax

 

 * settings

...

INSTALLED_APPS = [
    
    ...
    
    'myajax',
]

...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'test',                # DB명 : db는 미리 작성되어 있어야 함.       
        'USER': 'root',                # 계정명 
        'PASSWORD': '123',             # 계정 암호           
        'HOST': '127.0.0.1',           # DB가 설치된 컴의 ip          
        'PORT': '3306',                # DBMS의 port 번호     
    }
}

...

 => application 연결.

 => DB 설정

 

 

 * anaconda prompt

cd C:\work\psou\django_test11_ajax
python manage.py inspectdb > aaa.py

 

 

 * models

from django.db import models

# Create your models here.
class Sangdata(models.Model):
    code = models.IntegerField(primary_key=True)
    sang = models.CharField(max_length=20, blank=True, null=True)
    su = models.IntegerField(blank=True, null=True)
    dan = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'sangdata'

 => aaa.py의 사용할 table을 models.py에 복사 붙여넣기. (제작된 Table을 Django 형식으로 자동 생성)

 

 Make migrations - myajax

 Migrate

 

 

 * urls

from django.contrib import admin
from django.urls import path
from myajax import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.MainFunc),
    path('list', views.ListFunc),
    path('calldb', views.ListDbFunc),
]

 => url -> function 연결.

 => url '' -> MainFunc()

 => url 'list' -> ListFunc()

 => url 'calldb' -> ListDbFunc()

 

 

 * views

from django.shortcuts import render
from myajax.models import Sangdata
from django.http.response import HttpResponse
import json

# Create your views here.
def MainFunc(request):
    return render(request, 'main.html')

def ListFunc(request):
    return render(request, 'list.html')

def ListDbFunc(request):
    sdata = Sangdata.objects.all() # db sangdata 전체 읽기
    datas = []
    for s in sdata:
        #print(s.code)
        dict ={'code':s.code, 'sang':s.sang, 'su':s.su,'dan':s.dan}
        datas.append(dict)
    #print(datas)
    #[{'code': 1, 'sang': '장갑', 'su': 3, 'dan': 10000},
    # {'code': 2, 'sang': '벙어리장갑', 'su': 2, 'dan': 12000},
    # {'code': 3, 'sang': '가죽장갑', 'su': 10, 'dan': 50000}, 
    # {'code': 4, 'sang': '가죽점퍼', 'su': 5, 'dan': 650000}, 
    # {'code': 6, 'sang': '신상', 'su': 11, 'dan': 3000}, 
    # {'code': 7, 'sang': '아메리카노', 'su': 2, 'dan': 1}, 
    # {'code': 8, 'sang': '가방', 'su': 22, 'dan': 300}]
    return HttpResponse(json.dumps(datas), content_type='application/json')

 => MainFunc() -> main.html

 => ListFunc() -> list.html

 => ListDbFunc() : db data 읽은 후 json data send.(dict -> list -> str로 변환)

 

 

 * main.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>메인</h2>
<a href="/list">상품 보기</a>
</body>
</html>

 

 * list.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.js"></script>

<script type="text/javascript">
$(document).ready(function(){
	$("#btnOk").click(function(){
		$("#showData").empty();
		
		$.ajax({
			url:'calldb',
			type:'get',
			dataType:'json',
			success:function(data){
				//alert(data);
				let str = "<table border='1'>";
				str += "<tr><th>코드</th><th>상품명</th><th>수량</th><th>단가</th></tr>";
				let count = 0;
				$.each(data, function(ind, entry){
					str += "<tr>";
					str += "<td>" + entry['code'] + "</td>";
					str += "<td>" + entry['sang'] + "</td>";
					str += "<td>" + entry['su'] + "</td>";
					str += "<td>" + entry['dan'] + "</td>";
					str += "</tr>";
					count += 1;
				});
				
				str += "</table>";
				$("#showData").append(str);
				$("#showData").append("건수 : "+count);
			},
			errorLfunction(){
				$("#showData").text("로딩 실패");
			}
		});
	});
});
</script>

</head>
<body>
<h2>상품 목록</h2>
<button id="btnOk">상품자료 출력(Ajax)</button><br><br>
<div id="showData"></div>
<hr>
</body>
</html>

 => button click 시 ajax로 'calldb' 요청명 send 후 성공 시 table 형태로 조회된 DB 데이터 출력.


13. Join

 * views

SearchJikwonFunc(request):
    jikwon_jik = request.GET["jikwon_jik"]
    jikwonList = Jikwon.objects.extra(select={'buser_name':'buser_name'}, tables=['Buser'],
    where =['Buser.buser_no=Jikwon.buser_num']).filter(jikwon_jik = jikwon_jik)
    data = []
    for j in jikwonList:
        dict ={}
        dict['jikwon_no'] = j.jikwon_no
        dict['jikwon_name'] = j.jikwon_name
        dict['buser_name'] = j.buser_name
        data.append(dict)
    print(data)
    return HttpResponse(json.dumps(data), content_type = "application/json")

[목차]

8. Ajax

 

 

 

8. Ajax(Asynchronous Javascript And XML)

client request
--------->


response
<---------
server
1) 클라이언트의 뷰페이지에서 요청을
   보낸다.
2) XMLHttpRequest객체가 생성.
3) 요청처리.
6) 응답받은 메시지를 자바스크립트에서
   처리.(응답되는 데이터를 가지고 부분
   화면을 변경하기 위해서 javascript와
   DOM(JQuey) 사용)
7) 페이지를 업데이트.
4) 서버에서 request를 받는다.
5) request에 대한 처리(DBMS액세스)
    후 클라이언트에 응답을 보낸다.
    (데이터, 문자열, xml, json)

 

    [jsp]

    1) 버튼을 누르면 ajax요청을 하기 위해서 runAjax함수 호출.

<body>
	<form name = "myform">
		<input type="text" name="id">
		<button type="button" onclick="runAjax()">Ajax테스트</button>
	</form>
	<div id="result"></div>
</body>

 

    2) 비동기통신 처리를 할 수 있는 자바스크립트 객체를 생성 - XMLHttpRequest

<script type="text/javascript">
	function runAjax(){
		var xhr = new XMLHttpRequest();


    3-1) 요청설정

		open("request타입",url,true-async, false-sync)

     -GET

		xhr.open("GET","servlet 경로?id="+myform.id.value, true);

    - POST

		xhr.open("POST","/serverweb/ajaxtest_post.do", true);

    3-2) 요청보내기 - 비동기 통신으로 요청을 보낸다.

     -GET

		send(); // get방식
		xhr.send();

    - POST

		send("문자열"); // post방식
		xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
		xhr.send("id="+myform.id.value);

    => 요청헤더에 content-type을 변경.
    => form태그를 이용해서 요청하고 있지 않지만 form태그를 이용해서 요청하는 것처럼  key=value의 형식으로

        인코딩을 적용 .
    => ajax요청을 submit버튼을 눌러 요청할때 처럼 key를 이용해서 value를 추출해야 하므로 반드시 설정해야

        하는 정보.

 

    [servlet]

    4) 서버에서 request를 수신 - 처리

String id = request.getParameter("id");
String msg="";
if(id.equals("이미 존재하는 ID")) { // DBMS에서 처리
	msg="사용불가능 id";
}else {
	msg="사용가능 id";
}

 

    5) 클라이언트에 응답하기 위한 메시지를 만들어서 응답

        (문자열이 하나인 경우 변수처리해서 보낸다. json라이브러리를 이용해서 json객체를 만들어서 응답)

    - GET

response.setContentType("text/html;charset=UTF-8");
PrintWriter pw= response.getWriter();
pw.print(msg);

    - POST

response.setContentType("text/html;charset=UTF-8");
response.setHeader("cache-control", "no-cache, no-store");
PrintWriter pw= response.getWriter();
pw.print(msg);


    => response의 헤더 값을 변경.
    => html을 요청하는 것이 정적 리소스를 요청하는 작업이고 요청이 될때마다 서버에서 작업을 수행하고 실행해서

         결과를 가져오는데 이를 비효율적이라 판단해서 기본설정이 동일한 요청이 들어왔을떄 캐쉬에서 저장하고

         있는 파일을 보여준다.
         결과를 캐쉬에 저장하면 다음 요청에 대한 결과가 제대로 나오지 않을 수 있다. 그래서 응답결과를 캐쉬에 저장

         하지 말고 서버에서 바로바로 요청해서 보여줄 수 있도록 헤더값에 설정.

    [jsp]

    6) 서버와 비동기 통신을 하면서 XMLHttpRequest가 갖고 있는 readyState값이 지속으로 변경
       변경될때 마다 onreadystatechange이벤트가 발생하며 이 이벤트를 처리하기 위해서 익명함수를 콜백으로 정의

		xhr.onreadystatechange = function(){ // 함수 자동호출
			if(xhr.readyState == 4 && xhr.status==200){
			// 비동기 통신이 정상처리, http응답도 정상처리
				document.getElementById("result").innerHTML = xhr.responseText;
			}
		}
	}
</script>
		xhr.onreadystatechange = readyCallback;
	}
	function readyCallback(){
		if(xhr.readyState == 4 && xhr.status==200){
			document.getElementById("result").innerHTML = xhr.responseText;
		}
	}
</script>

    * readyState

    0: request가 초기화되지 않은 상태

    1: 서버와 연결이 된 상태

    2: 요청을 받은 상태

    3: 요청을 처리하고 있는 상태

    4: 요청처리가 끝나고 응답 대기 상태

 

    * status

    200 : 정상완료

    404 : 페이지가 존재하지 않는 경우

 

    * 서버응답 처리 객체

    responseText : String데이터를 get으로 응답받은 경우 사용

    response​XML : XML데이터를 get으로 응답받은 경우 사용

+ Recent posts

1