티스토리 뷰
저번 글과 이어서 진행하도록 하겠습니다. 저번 글에서는 Django와 MySQL을 연동하는 작업까지만 하고 마쳤습니다.
이번에는 쿼리문을 작성하여 MySQL에 저장되어있는 데이터를 가져와 view에서 사용하려 합니다. MySQL을 사용하더라
도 기존에 우리가 사용한 objects.all(), objects.get() 등의 queryset을 통하여 데이터를 가져올 수 있습니다. 하지만 SQL문
을 사용하는 것이 Django 외의 프로그래밍 영역에서 활용도가 훨씬 높기 때문에 SQL문을 사용하기로 합니다.
(+ SQL문 연습)
1. BookListView 변경
# 새로 import 하는 모듈
from django.db import connection
def BookListView(request):
# books = Book.objects.all()
try:
cursor = connection.cursor()
strSql = "SELECT code, name, author FROM bookstore_book"
result = cursor.execute(strSql)
books = cursor.fetchall()
connection.commit()
connection.close()
except:
connection.rollback()
print("Failed selecting in BookListView")
return render(request, 'book_list.html', {'books': books})
- connection: 데이터베이스에 접속을 하기 위한 모듈
- settings.py에 입력한 데이터베이스 정보를 가지고 접속
- cursor(): cursor 객체 생성
- cursor 란 SQL문을 수행하고 결과를 얻는데 사용하는 객체
- cursor.execute(): 쿼리문을 연결된 DB로 보내 쿼리를 실행
- cursor.fetchall(): 쿼리 실행 결과로 반환된 전체 데이터를 데이터베이스 서버로부터 가져옴
- connection.commit(): 데이터에 대한 변경사항이 있다면 이를 확정, 갱신
- connection.close(): 데이터베이스와의 연결을 닫음
- connection.rollback(): 쿼리문 실행 도중 잘못된 경우 실행 전으로 되돌려 놓음
위의 코드를 작성 후 실행시키면 아래 화면과 같이 바로 에러가 납니다.
에러 내용을 보니 detail url 패턴에 code라는 인자가 필요한데 그 자리에 아무 것도 없다는 내용입니다.
디버깅 모드로 데이터가 어떻게 들어왔는지 살펴보니 데이터들이 하나의 객체가 아닌 튜플로 들어온 것을
확인할 수 있습니다. (디버깅 모드는 추후 글 작성 예정)
즉, 각 로우 별로 어떤 컬럼의 값인지 상세 정보가 들어있는 것이 아니라 단순히 로우 별로 쿼리문에서
선택한 컬럼 값들만 순서대로 가져와 나열한 것입니다. 따라서, 우리가 이 결과 값들을 가지고 각 값이
어떤 컬럼의 값인지 알기 쉽고, 템플릿에서 사용하기 쉽도록 데이터를 구성해야 합니다.
BookListView 코드를 다음과 같이 변경합니다.
def BookListView(request):
# books = Book.objects.all()
try:
cursor = connection.cursor()
strSql = "SELECT code, name, author FROM bookstore_book"
result = cursor.execute(strSql)
datas = cursor.fetchall()
connection.commit()
connection.close()
books = []
for data in datas:
row = {'code': data[0],
'name': data[1],
'author': data[2]}
books.append(row)
except:
connection.rollback()
print("Failed selecting in BookListView")
return render(request, 'book_list.html', {'books': books})
위의 코드로 작성한 후 실행해보면 북리스트 페이지에서 다음과 같이 책 제목이 나오지 않고 딕셔너리 자료형 하나가
통째로 나옵니다.
book_list.html 파일을 살펴보면 원인은 바로 제목 부분에 book이라는 변수 자체를 사용하고 있기 때문이라는 것을
알 수 있습니다.
이전에 queryset을 사용할 때는 books는 세 개의 객체가 담긴 리스트였고 book은 하나의 객체에 해당되었습니다.
이 객체를 직접 사용할 때는 우리가 models.py의 Book 모델에 정의한 것처럼 해당 객체의 name 컬럼이 반환되도록
메소드를 정의했기 때문에 책 제목이 나왔습니다. 하지만 SQL문을 사용할 때는 데이터베이스로부터 객체가 아닌 단순 컬럼 값만을 가져와 사용하기 쉽도록 데이터를 구성했습니다.
따라서 현재 템플릿에 넘어온 books는 세 개의 딕셔너리 데이터가 있고 book은 하나의 딕셔너리에 해당됩니다.
그렇기 때문에 book을 그대로 사용하면 딕셔너리가 보이는 것입니다.
딕셔너리 중 책 제목 데이터를 가지고 있는 키 값을 template에 지정하여 책 제목이 나오도록 한다.
<li><a href="{% url 'bookstore:detail' book.code %}"> 제목: {{book.name}}</a><br>저자: {{book.author}}</li>
다음 코드를 작성한 후 실행하면 이전과 같이 올바르게 나온 것을 확인할 수 있습니다.
2. BookDetailView 변경
BookListView와 같은 방식으로 BookDetailView의 코드를 변경합니다.
def BookDetailView(request, code):
# book1 = get_object_or_404(Book, code=code)
# book2 = Book.objects.get(code=code)
try:
cursor = connection.cursor()
strSql = "SELECT code, name, author, price, url FROM bookstore_book WHERE code = (%s)"
result = cursor.execute(strSql, (code,))
datas = cursor.fetchall()
connection.commit()
connection.close()
book = {'code': datas[0][0],
'name': datas[0][1],
'author': datas[0][2],
'price': datas[0][3],
'url': datas[0][4]}
except:
connection.rollback()
print("Failed selecting in BookListView")
return render(request, 'book_detail.html', {'book': book})
(%s)
: string 타입의 문자열 포매팅- 문자열 포매팅: 문자열 안에 어떤 값을 삽입하는 방법
- 문자열 안의 특정한 값을 바꿔야 할 경우가 있을 때 이것을 가능하게 해줌
- 문자열 포매팅: 문자열 안에 어떤 값을 삽입하는 방법
cursor.execute(strSql, (code,))
: 쿼리문을 실행하는데 포매팅된 부분을 code로 치환- 튜플 안에 값이 하나만 있는 경우, 꼭 뒤에 콤마를 붙여야 함. 그렇지 않으면 튜플이 아닌
- 일반 괄호로 인식
datas[0][0]
: 이중 튜플로 결과값이 반환되기 때문에 이런 방식으로 인덱싱을 해야 함
참고 자료
'Django' 카테고리의 다른 글
[issue #002] django.db.utils.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' (10061)") (0) | 2020.01.09 |
---|---|
[issue #001] mysqlclient가 설치되지 않을 때 (0) | 2020.01.09 |
[Django App 2-2] Django와 MySQL 연동하기 (0) | 2020.01.07 |
[Django App 2-1] 북스토어 애플리케이션 개발 (0) | 2020.01.07 |
[Django App 1-3] 북마크 애플리케이션 개발(2) (0) | 2020.01.01 |
- Total
- Today
- Yesterday
- Django application
- query parameter
- Django 팔로우
- 서점 어플리케이션
- Django 로그아웃
- 파이썬
- Django 어플리케이션
- Django 로그인
- Django 업로드
- Django 검색
- python
- Django 회원 정보 수정
- Django Instagram
- Django 인스타그램
- Django 좋아요
- Django 북마크
- 북마크 어플리케이션
- Django 프로젝트 생성
- Django 비밀번호 수정
- Redis
- Django 회원가입
- Django
- Django 해시태그
- MySQL
- Django 컬렉션
- Django 댓글
- Redis Cache
- java
- 장고
- Django User
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |