일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Join
- TensorFlow
- read_table
- to_html
- 코딩생활
- read_csv
- 강남데이트
- DataFrame
- topic생성
- find()
- pandas
- groupby
- select_related()
- read_excel
- to_json
- kafka설치
- find_all()
- select_one()
- 갈비스테이크
- to_csv
- pivot_table
- read_fwf
- iloc
- webscrap
- 강남 녘
- keras
- 웹스크랩
- findall()
- to_excel
- 녘
- Today
- Total
자드's
[Django] ForeignKey를 이용해서 다른 테이블의 정보를 불러와서 웹브라우저에 출력해보자 select_related() 본문
[Django] ForeignKey를 이용해서 다른 테이블의 정보를 불러와서 웹브라우저에 출력해보자 select_related()
최자드 2022. 10. 22. 01:57아래와 같이 고객 정보를 입력해서 담당 직원의 정보를 불러오는 문제를 받았다.
??? 쉽네??? 라고 생각했다
5시간을 고민하기 전까지...
MariaDB에 저장 되어있는 정보에서 연결고리를 찾아보기
고객 테이블이다
요기 있는 이름과 전화번호를 입력하면
아래의 직원 테이블에 있는 직원의 이름, 직급 평점, 근무연수
부서 테이블에 있는 부서 전화번호와 부서 이름이
클라이언트에게 출력이 되도록 코드를 짜야한다
Django 프로젝트의 기본 셋팅
자 먼저 제일 기본적인 django 프로젝트 셋팅을 해줄 것이다
기본중의 기본 어플리케이션을 만들어 주고 settings.py에 어플리케이션을 install 해준다
간단한(?) 코드라고 생각했기에 Function view 방식으로 코드를 짜볼 생각이다
메인페이지에서 검색을 하고
show요청이 들어오면 결과를 출력할 생각으로
path는 두개만 만들었다
자, 먼저 검색을 위한 main.html 파일과
결과 출력을 위한 show.html 파일을 templates에 만들어줬다
여기까지는 참 평화로웠어요 ㅎㅎㅎ
DB모델을 추가하고 정보를 불러와보기
models.py에 고객, 직원, 부서 테이블을 위한
클래스를 추가해주고
make migrations, migrate 를 해줬다
직원과 고객을 연결하기위한 ForeighKey가 보인다.....
(이것이 고뇌의 시발점)
from django.db import models
class Buser(models.Model):
buser_no = models.IntegerField(primary_key=True)
buser_name = models.CharField(max_length=10)
buser_loc = models.CharField(max_length=10, blank=True, null=True)
buser_tel = models.CharField(max_length=15, blank=True, null=True)
class Meta:
managed = False
db_table = 'buser'
class Gogek(models.Model):
gogek_no = models.IntegerField(primary_key=True)
gogek_name = models.CharField(max_length=10)
gogek_tel = models.CharField(max_length=20, blank=True, null=True)
gogek_jumin = models.CharField(max_length=14, blank=True, null=True)
gogek_damsano = models.ForeignKey('Jikwon', models.DO_NOTHING, db_column='gogek_damsano', blank=True, null=True)
class Meta:
managed = False
db_table = 'gogek'
class Jikwon(models.Model):
jikwon_no = models.IntegerField(primary_key=True)
jikwon_name = models.CharField(max_length=10)
buser_num = models.IntegerField()
jikwon_jik = models.CharField(max_length=10, blank=True, null=True)
jikwon_pay = models.IntegerField(blank=True, null=True)
jikwon_ibsail = models.DateField(blank=True, null=True)
jikwon_gen = models.CharField(max_length=4, blank=True, null=True)
jikwon_rating = models.CharField(max_length=3, blank=True, null=True)
class Meta:
managed = False
db_table = 'jikwon'
처음엔 그저 쉬워서 간단하게 끝날 줄 알았다
그냥 입력창에서 이름 전화번호 받아와서 if 문으로 비교해서 옮겨오면 되지
join 하면 금방 끝날 일 아닌가?
여러 생각이 머릿속을 스쳐 지나갔지만
막상 짜보니 그렇지 않았고 처음 배웠다보니 응용도 만만치않았다
처음엔 gogek_damsano에 Foreignkey가 있으니
Gogek.objects.all()로 데이터를 불러와서 gogek.gogek_damsano 를 콘솔창에 출력을 해보았다
결과는......
jikwon object (5)......
고난의 시작이었다.. 어떻게든 int type으로 뽑아보려고 노력했지만 도저히 안됐다
(얕은 지식으로 얕봤던 나 반성해)
Foreignkey를 이용한 select_related( )메소드 사용
구글링을 해보다가 select_related()의 사용법이 눈에 띄었다
sql 문으로 따지면 join을 하는 방법이라고 했다
그래...!! 이거야!!! 내가 찾던게 !!
라고했지만 사용법을 정확히 모르겠어서 고생을 많이 했다
찾으면서 하다보니 배운건
( ) 안에 Foreignkey를 넣어주고 받아오는
즉, models.py에서 받아오는 대상으로 작성한 Jikwon 클래스의 필드를 받아올 수 있다는 것 이었는데
여기서 중요한건,
jdata=Gogek.objects.select_related('gogek_damsano').get(gogek_name=gogek1.gogek_name)
name=jdata.gogek_damsano.jikwon_name
name 이라는 변수명으로 jikwon_name을 받아올 때
gogek_damsano.jikwon_name
Foreignkey를 가지고 있는 Gogek 필드의 이름에 " . " 을 찍어서 사용해야 한다는 것...
(이걸 몰라서 진짜 몇시간을 헤메인건지...)
결국, main.html에서 고객정보 (이름, 전화번호)를 입력했는데
이름을 받아와서 그 고객의 이름을 매개로 DB에서 받아왔다
get(gogek_name=gogek_name)
from django.shortcuts import render
from moonjae.models import Gogek, Buser, Jikwon
from datetime import datetime,date
# Create your views here.
def main(request):
return render(request,'main.html')
def show(request):
gogek1=Gogek.objects.get(gogek_name=request.POST.get('gname'))
try:
jdata=Gogek.objects.select_related('gogek_damsano').get(gogek_name=gogek1.gogek_name)
'''name=jdata.gogek_damsano.jikwon_name
jik=jdata.gogek_damsano.jikwon_jik
rating=jdata.gogek_damsano.jikwon_rating
gen=jdata.gogek_damsano.jikwon_gen
ibsail=jdata.gogek_damsano.jikwon_ibsail
num=jdata.gogek_damsano.buser_num''' # 이 내용을 전체를 담은게 datas
datas=jdata.gogek_damsano
day=date.today()-datas.jikwon_ibsail
gunmu=day.days//365
buser=Buser.objects.get(buser_no=datas.buser_num)
except Exception as e:
print('error: ',e)
# return render(request,'show.html',{'name':name,'jik':jik,'rating':rating,'gen':gen,'bname':bname,'btel':btel,'gunmu':gunmu})
return render(request,'show.html',{'datas':datas, 'gunmu':gunmu,'buser':buser})
기쁨에 심취한 나머지 jikwon 데이터를 하나하나 변수에 담아서 전달해줬었다
(나중에 datas로 한번에 넘겨줌)
buser의 정보는 간단하게 get(buser_no=datas.buser_num)
즉, jikwon 테이블에 있는 buser_num을 통해서 불러왔고
근무년수는 입사일과 datetime.date.today()를 통해서 구해줬다
(입사일도 datetime.date type이었음)
이런저런 고비를 넘기고 결과를 출력할 show.html 페이지를 작성했다
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body style="margin:30px">
<h1>담당 직원</h1> <br />
<table class="table table-bordered" border="1" style="width:40%; text-align: center; height:200px;">
<tr>
<td rowspan="2">
{% if datas.jikwon_gen == "남" %}
<img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fimgnews.naver.net%2Fimage%2F311%2F2022%2F08%2F16%2F0001489080_005_20220816125501827.jpg&type=sc960_832" width="150" height="180"/>
{% else %}
<img src="https://search.pstatic.net/common/?src=http%3A%2F%2Fblogfiles.naver.net%2FMjAyMjA4MDNfMTk4%2FMDAxNjU5NTIzNjU4MTAx.CVqH2ymt5isyDD07qSWn0A7Su4n_AAsU9-iv4oTVQ28g.aTMZ9FBcn2nZXFUumExTaLKICNAWUtF3CAJsT7WPlAYg.JPEG.v19891213v%2FNUTRIVILLE_%25B1%25A4%25B0%25ED_%25BC%25D5%25BF%25B9%25C1%25F8_%25B1%25CD%25B0%25C9%25C0%25CC_%25C1%25A4%25BA%25B8_%25282%2529.jpg&type=sc960_832" width="150" height="180"/>
{% endif %}
</td>
<td>직원명</td>
<td>{{datas.jikwon_name}}</td>
<td>직급</td>
<td>{{datas.jikwon_jik}}</td>
</tr>
<tr>
<td>부서명</td>
<td>{{buser.buser_name}}</td>
<td>부서전화</td>
<td>{{buser.buser_tel}}</td>
</tr>
<tr>
<td>근무연수</td>
<td colspan="2">{{gunmu}}</td>
<td>평점</td>
{% if datas.jikwon_rating == "a" %}
<td>최우수</td>
{% elif datas.jikwon_rating == "b" %}
<td>우수</td>
{% elif datas.jikwon_rating == "c" %}
<td>일반</td>
{% endif %}
</table>
</body>
</html>
자...!! 이제 결과를 출력할 일만 남았다
즐거운 마음으로 결과를 출력했다
멋지게 결과가 출력되었다
기쁨의 눙무리....
이걸로 django 를 학습하면서 첫 문제를 해결했다
spring과 다른 묘한 매력을 담은 django...
( 사원 사진이 예뻐서 그런거 아님)
get과 select_related 말고도 여러가지 방식이 있으니 더 정진해야겠다
그럼 20000
ps. 고객 이름이랑 전화번호 둘 다 받아와서 비교해야하는데 이름만 받아와서 틀린거 안 비밀
(다른 간단한 방법이 있는데 join에 정신 팔려서 오래걸린건 더 안 비밀)