Django AJAX + 예제

kangjuju·2023년 4월 24일
0

Django

목록 보기
5/6

JSON EN/DE CODING

AJAX를 사용하려면 Django Python의 object (dict/list/tuple/set)를
JSON문자열로 변경해 바이너리 형태로 전송해야 한다.

먼저 view에서 dict타입의 자료를 임의로 만들었다.

lan = { #dict type
    'id':11,
    'name':'파이썬',
    'history':[
        {'date':'2020-4-24','exam':'basic'},
        {'date':'2023-4-24','exam':'django'}
    ]
}

dumps

  • dict타입을 json문자열(str)로 변환(인코딩)
def testFunc():
    #json encoding / decoding
    print(type(lan))
    print('==============')
    #dict -> str으로 변환
    jsonString = json.dumps(lan,indent=4) #indent는 확인용
    print(type(jsonString))

loads

  • json 문자열(str) 을 dict타입으로 변환 (디코딩)
    #json decoding
    mydic = json.loads(jsonString)
    print(type(mydic))
    print(mydic['name']) #dict제공 명령 사용 가능
    for h in mydic['history']:
        print(h['date'],h['exam'])

출력

Promise

//js fetch(promise)
document.querySelector("#btn3").onclick = function(){
	const url = "goajax";
	fetch(url).then(res => {
		if(res.status === 200){
			return res.json();
		}else{
			console.log(`HTTP Error! status:${res.status}`);
		}
	}).then(jsonData => {
		process3(jsonData);
	}).catch(err => {
		console.log(err)
	})
}

function process3(jsonData){
	let str=""
		for(let i=0; i < jsonData.length; i++){
			str += jsonData[i].irum + " " + jsonData[i].nai + "<br/>";
		}
	document.querySelector("#showData3").innerHTML = str;
}

<body>
자료입력 : <input type='text' id="txtMsg" value="korea">
<button id="btn1">AJAX test1</button>
<br>
<div id="showData1"></div>
</body>

여기서 보낸 요청을 view에서 받아보자

def GoFunc(request):
    datas = [
        {'irum':'홍길동','nai':22},
        {'irum':'신길동','nai':32},
        {'irum':'고길동','nai':42},
    ]
    return HttpResponse(json.dumps(datas),content_type="application/json") 

DB사용

XML 과 fetch 두가지 방법 사용.

window.onload = function(){
	//레거시(XML) 방법
	document.querySelector("#btnOk1").onclick = function(){
		xhr = new XMLHttpRequest();
		xhr.onreadystatechange = function(){
			if(xhr.readyState === XMLHttpRequest.DONE){
				if(xhr.status === 200){
					process1();
				}}}
		xhr.open("GET",'calldb1',true)
		xhr.send();
	}
	
	//fetch(Promise)
	document.querySelector("#btnOk2").onclick = function(){		
		const url = "calldb2";
		fetch(url).then(res => {
			if(res.status === 200){
				return res.json();
			}else{
				console.log('error');
			}
		}).then(jsonData => {
			process2(jsonData);
		}).catch(err => {
			
		})
	}
}

// legacy
function process1(){
	let parseData = JSON.parse(xhr.responseText);
	let str= "<table border='1'>";
	str += "<tr><th>코드</th><th>품명</th><th>수량</th><th>단가</th></tr>"
	let count = 0;
	for(let i=0; i < parseData.length; i++){
		str += "<tr>"
		str += "<td>" + parseData[i].code + "</td>";
		str += "<td>" + parseData[i].sang+ "</td>";
		str += "<td>" + parseData[i].su + "</td>";
		str += "<td>" + parseData[i].dan+ "</td>";
		str += "</tr>";
		count += 1;
	}
	str += "</table>";
	document.querySelector("#showData1").innerHTML = str;
}

//fetch(Promise)
function process2(jsonData){
  for(let i=0; i < jsonData.length; i++){
		str += "<tr>"
		str += "<td>" + jsonData[i].code + "</td>";
		str += "<td>" + jsonData[i].sang+ "</td>";
  ..
  .
  }
  • views
def ListDbFunc(request):
    sdata = Sangdata.objects.all()
    datas = []
    for s in sdata:
        dic = {'code':s.code,'sang':s.sang,'su':s.su,'dan':s.dan}
        datas.append(dic)
        
    return HttpResponse(json.dumps(datas),content_type="application/json")

예제 (ajax + ORM)

각 GET 요청에 따른 urls에서의 설정을 잊지말자.

html

  • ajax fetch 사용
<body>
<h2>MAIN</h2>
직원정보 입력<br> <b>[사원 대리 부장 과장 이사]</b>
<br>
직급: <input type='text' id="jik" value="대리">
<button id="btn1">결과보기</button>
<div id="showData1"></div>
<hr>
<form>
	<table id='frm'>
		<tr><td>자료 입력</td></tr>
		<tr><td>직원번호 :</td><td><input type='text' id="no"></td>
		<tr><td>직원명 :</td><td><input type='text' id="name"></td>
		<tr><td>부서명 :</td><td><input type='text' id="buser"></td>
		<tr><td>성별 : </td><td><input type='text' id="gen"></td>
		<tr><td>입사년 :</td><td><input type='text' id="year"></td>
		<tr><td>보유기술 :</td><td><input type='text'></td>
		<tr><td><button id="btn2">등록</button></td>
	</table>
</form>
</body>

javascript

    1. 직무 검색 요청
    1. 출력
    1. input에 직원 정보 삽입
  1. 직무 검색 요청
window.onload = function(){
	document.querySelector("#btn1").onclick = function(){
			const url = "jikwonlist?jik="+document.querySelector("#jik").value;
			fetch(url).then(res => {
				if(res.status === 200){
					return res.json();
				}else{
					console.log(`HTTP Error! status:${res.status}`);
				}
			}).then(jsonData => {
				jikwonProcess(jsonData);
			}).catch(err => {
				console.log(err)
			})
		}else{
			alert('없는 직무입니다.')
		}
	}
}
  1. 출력. 직원명에 a태그로 요청한다. onclick사용
function jikwonProcess(jsonData){
	let str= "<table border='1'>";
	str += "<tr><th>No</th><th>이름</th><th>부서명</th></tr>"
	let count = 0;
	if(jsonData.length > 0){
		for(let i=0; i < jsonData.length; i++){
			str += "<tr>"
			str += "<td>" + jsonData[i].no + "</td>";
			str += "<td> 
          <a href='#' onclick='infoProcess("+jsonData[i].no+")'>"+jsonData[i].name+ "</a></td>";
			str += "<td>" + jsonData[i].buser + "</td>";
			str += "</tr>";
			count += 1;
		}		
	}else{
		alert('검색결과가 없습니다')
		return
	}
	str += "<tr><td colspan='3'> 인원수 : "+count+" 명</td></tr></table>";
	document.querySelector("#showData1").innerHTML = str;

}
  1. input에 직원 정보 삽입
function infoProcess(no){
	const url = "jikwoninfo?no="+no;
	fetch(url).then(res => {
		if(res.status === 200){
			return res.json();
		}else{
			console.log(`HTTP Error! status:${res.status}`);
		}
	}).then(jsonData => {
		document.querySelector("#no").value = jsonData['0'].no;
		document.querySelector("#name").value = jsonData['0'].name;
		document.querySelector("#buser").value = jsonData['0'].buser;
		document.querySelector("#gen").value = jsonData['0'].gen;
		document.querySelector("#year").value = jsonData['0'].year;
	}).catch(err => {
		console.log(err)
	})
}

views

  • ORM join을 위해 extra 함수를 사용했다
# 메인화면 출력
def MainFunc(request):
    return render(request, 'main.html')

#버튼 클릭시 ORM을 이용한 검색결과 JSON반환
def JikFunc(request):
    jikwons = Jikwon.objects.filter(jikwon_jik=request.GET['jik']).extra(
    select={'buser_name': 'buser.buser_name'},
    tables=['buser'],
    where=["jikwon.buser_num = buser.buser_no"]
    )
    
    
    datas = []
    for j in jikwons:
        dic = {'no':j.jikwon_no,
               'name':j.jikwon_name,
               'buser':j.buser_name}
        datas.append(dic) 
    
    return HttpResponse(json.dumps(datas),content_type="application/json")
    
 #이름 클릭시 ORM을 이용한 JSON데이터 반환
def InfoFunc(request):
    info = Jikwon.objects.filter(jikwon_no=request.GET['no']).extra(
    select={'buser_name': 'buser.buser_name'},
    tables=['buser'],
    where=["jikwon.buser_num = buser.buser_no"])
    
    datas = []
    for i in info:
        dic = {'no':i.jikwon_no,
               'name':i.jikwon_name,
               'gen':i.jikwon_gen,
               'buser':i.buser_name,
               'year': i.jikwon_ibsail.strftime('%Y')}
        datas.append(dic)
    
    return HttpResponse(json.dumps(datas),content_type="application/json")

참고

ORM related

  • 위의 예제에서 외래키로 잘 지정되어 있다면 related를 사용하는것이 더 좋다.
    extra함수로 join 대신 아래의 방법을 사용하다
# 직급별 직원 정보 
jikData=Jikwon.objects.select_related('buser_num').filter(jikwon_jik=request.GET.get("jikwon_jik"))

#직원정보
jikwon=Jikwon.objects.select_related("buser_num").get(jikwon_no=request.GET.get("jikwon_no"))
ibsaYear=jikwon.jikwon_ibsail.year  # 입사년도만 저장
        

또한 filter에서 join 테이블 컬럼에 대해 검색을 하고싶다면
Jikwon.objects.select_related('buser_num').filter(buser_num__buser_name = request...)
와 같이 외래키로 접근 후 언더바2개로 컬럼을 접근한다

0개의 댓글