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() 메소드를 이용하는 것이 추가적인 데이타 처리가 필요없고, 코드도 간결해지는 것을 볼 수 있다.