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. 조인(join) : 여러 테이블을 연결해서 필요한 데이터를 조회하는 방법
    - 오라클 조인 : 여러테이블 연결조건을 where절에 정의
    - ANSI 조인(표준)

    1) 개요 : 정규화된 여러 테이블의 데이터를 이용해서 데이터를 조회해야하는 경우 테이블 조인을 한다.
    - 조인은 관계형 데이터 베이스에서의 중요기능.
    - 기본키와 외래키 관계를 이용해서 테이블을 조인해야한다.
    - 조인을 하는 경우 반드시 조인 조건 정의.
  
    2) 조인 사용방법
    - from절에 테이블을 정의할 때 alias를 이용해서 정의.

select d.dname, e.ename, e.sal
from emp e, dept d
where e.deptno=d.deptno and sal>2000;
select e.empno, e.ename, e.job, e.deptno, d.deptno, d.dname
from emp e, dept d
where e.deptno=d.deptno;
select d.deptno, d.dname, l.city
from dept d, locations l
where d.loc_code=l.loc_code;

     -> deptno : 기본키


  - select절에서 두 개 이상의 테이블에 있는 칼럼을 추가하는 경우 from절에서 정의한 alias를 이용해서 칼럼의 모호성 제거.
  - where절에서는 반드시 조인조건을 정의해야한다. 조인을하면 외래키 테이블의 외래키와 기본키 테이블의 기본키를 비교하고 일치하는 레코드의 원하는 값을 가져오므로 조건을 정의하지않으면 데이터를 조회할 수 없다.
  - 사용되는 모든 테이블의 조인조건을 정의해야한다. (테이블이 세개면 조인 조건은 두개 정의)

select e.ename, d.dname, e.sal, l.city
from emp e, dept d, locations l
where e.deptno=d.deptno and d.loc_code=l.loc_code;

    - 검색 조건 추가
      where 조인조건
      and 조건추가

select e.empno, e.ename, e.sal, d.dname, d.loc_code
from emp e, dept d
where job='SALESMAN'
and e.deptno=d.deptno;
select ename, sal, hiredate
from emp e, dept d, locations l
where l.city = 'SEOUL'
        and e.deptno=d.deptno and d.loc_code=l.loc_code;
select e.ename, e.sal, e.job, e.hiredate, e.comm
from emp e, dept d, locations l
where e.deptno=d.deptno and d.loc_code=l.loc_code
and l.city='DALLAS' and e.sal>=1500;
select d.department_name, count(e.employee_id)
from employees e, departments d
where e.department_id = d.department_id
group by department_name;
select e.first_name || e.last_name || '의 연봉은 ' || e.salary
|| ' 입니다.' as 결과
from employees e,departments d
where e.department_id = d.department_id
and d.department_name = 'IT'
order by salary asc;
select e.employee_id, e.first_name, j.job_title, d.department_name
from employees e, departments d, locations l, jobs j
where e.department_id=d.department_id
and d.location_id = l.location_id
and e.job_id=j.job_id
and l.city ='Seattle';
select j.job_title job, sum(e.salary) 급여
from employees e, jobs j
where j.job_title not like '%Representative%'
      and j.job_id=e.job_id
group by j.job_title
having sum(e.salary)>30000
order by sum(e.salary);
select d.department_name 부서명, count(e.department_id) 인원수
from employees e, departments d
where e.department_id = d.department_id
      and hire_date <'2005-1-1'
group by d.department_name;
select d.department_id 부서번호, d.department_name 부서명, count(e.employee_id) 인원수,
 max(e.salary) 최고급여, min(e.salary) 최저급여, floor(avg(e.salary)) 평균급여, sum(e.salary) 급여총액
from employees e, departments d
where e.department_id = d.department_id
group by d.department_id, d.department_name
having count(e.department_id)>=3
order by 인원수 desc;
select j.job_title job, sum(e.salary) 급여
from employees e, jobs j
where j.job_title not like '%Representative%'
      and j.job_id=e.job_id
group by j.job_title
having sum(e.salary)>30000
order by sum(e.salary);
select d.department_name, floor(avg(salary)) 평균연봉
from employees e, departments d
where e.department_id=d.department_id
group by d.department_name
having avg(salary)>= 5000
order by 평균연봉 desc; 


  3) 조인의 종류(oracle 조인)
   ① Equip 조인 : 두개 이상의 테이블에서 칼럼 값이 정확하게 일치하는 경우 조회.
    조인조건 : where 기본테이블.기본키 = 외래키테이블.외래키
        (테이블은 alias 사용가능)

select e.ename d.dname
from emp e, dept d
where e.deptno = d.deptno


   ② outer 조인
   - 조인 적용했을 때 조인 조건을 만족하지않는 데이터를 조회하고 싶을때 사용.
   - (+) 연산자를 한쪽 칼럼에 초가해서  사용.
   - 만족하지 않아도 한쪽테이블의 모든 데이터를 조회해서 볼 수 있도록 자원.
   - (+)가 추가되면 만족되지 않는 조건을 임의로 추가해서 비교하므로 (+)가 투가되지않은 테입르의 레코드가 

     출력된다.
   [구문]

select 테이블명1(alias1명).칼럼며으 테이블2 alias2
from 테이블명1 alias1, 테이블명2 alias2
where 테이블명1(alias1).칼럼명(+) = 테이블명2(alias).칼럼명(+)

    - dept table에 null을 추가하여 emp table과 비교하여 emp table의 null data를 조회한다.

    - Equip 조인은 조인문에 detno가 일치하지않거나 null인 경우 조회되지않는다.

select e.empno, d.dname, e.ename, e.sal
from emp e, dept d
where e.deptno = d.deptno(+);
select nvl(m.ename,'관리자없음') 관리자명, count(e.empno) 인원수
from emp e, emp m
where e.mgr=m.empno(+)
group by m.ename;
select j.job_title, count(e.employee_id)
from employees e, jobs j
where e.job_id=j.job_id(+)
group by j.job_title;

    - emp table에 null을 추가하여 dept table과 비교하여 dept table의 null data를 조회한다.

select e.empno, d.dname, e.ename, e.sal
from emp e, dept d
where e.deptno(+) = d.deptno;
select d.department_name, count(e.employee_id)
from employees e, departments d
where e.department_id(+)=d.department_id
group by d.department_name
order by d.department_name;


   ③ non-Equip 조인(등급표 조인)
    - 두테이블에서 비교해야하는 칼럼 값이 정확하게 일치하지않고 사이 값인 경우 조인하는 방법. =연산자를 

      사용하지않은 조인.

select e.empno, e.sal, g.grade
from emp e, salgrade g
where e.sal between g.losal and g.hisal;


   ④ self 조인
    - 같은 테이블에서 조인하는 경우.
    - 하나의 테이블의 다른 칼럼을 가지고 조인하며 서로 다른 테이블인 것처럼 작업할 수 있다.
    - 조인조건은 equip조인과 동일하게 정의

select e.empno 사원번호, e.ename 사원명, e.mgr 관리자코드, m.ename 관리자명
from emp e, emp m
where e.mgr=m.empno;
select e.employee_id, e.first_name, nvl(m.first_name,'관리자 없음') 관리자명
from employees e, employees m
where e.manager_id = m.employee_id(+)
      and e.first_name like '_t%';
select e.first_name, e.salary
from employees e, employees m
where e.manager_id = m.employee_id
      and e.salary>m.salary;

 

 

+ Recent posts

1