django를 사용하다보면, 복잡한 sql문을 django ORM으로 만들기가 매우 어려운 경우가 발생한다.
이럴 때, sql을 직접 이용하기 위해서 djanco connection을 사용할 수도 있지만, query 결과를 템플릿으로 전달하는데는 django queryset이 더 유리해 보인다.
1. app/models.py 에 아래와 같은 테이블을 만들고 migrate한다.
from django.db import models
# Create your models here.
class TestData(models.Model):
ip = models.GenericIPAddressField()
mac = models.CharField(max_length=12, default='000000000000')
date = models.DateTimeField(null=True)
explane = models.CharField(max_length=64, null=True)
2. connect를 이용하는 방법.
app/views.py에 코드 작성.
from django.views.generic import View
from django.db import connection
from .models import TestData
class ConnectView(View):
template_name = 'result.html'
def get(self, request):
query = 'select * from green_testdata'
#query = 'insert into green_testdata(ip, mac, date, explane) values ("192.168.0.2", "aa000a001001", "2019-07-17 11:31", "Test data")'
cursor = connection.cursor()
row = cursor.execute(query)
datas = row.fetchall()
data = list()
for i in datas:
d = dict()
d['id'] = i[0]
d['ip'] = i[1]
d['mac'] = i[2]
d['date'] = i[3]
d['explane'] = i[4]
data.append(d)
print(data)
return render(request, self.template_name, {'data': data})
template를 아래와 같이 작성한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Connect</title>
</head>
<body>
{% for i in data %}
{{ i.ip}} | {{ i.mac }}
{% endfor %}
</body>
</html>
3. Django orm의 raw() 메소드 이용하는 방법
아래와 같은 view를 만든다.
class QueryView(View):
template_name = 'result.html'
def get(self, request):
query = 'select * from green_testdata';
data = TestData.objects.raw(query)
#data = TestData.objects.all()
print(data)
return render(request, self.template_name, {'data': data})
템플릿은 이전에 만든 result.html을 동일하게 사용한다.
4. urls.py에 url을 등록한다.
from django.urls import path
from .views import ConnectView, QueryView
urlpatterns = [
path('connect/', ConnectView.as_view(), name='connectview'),
path('query/', QueryView.as_view(), name='queryview'),
]
이제 테스트서버를 실행하고 웹브라우저에 localhost:8000/connect/, localhost:8000/query/ 를 입력하면 동일한 결과를 볼 수 있다.
결과적으로 django에서 sql을 직접 실행하려면 raw() 메소드를 이용하는 것이 추가적인 데이타 처리가 필요없고, 코드도 간결해지는 것을 볼 수 있다.