django, ORM raw() vs connection

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

답글 남기기

Your email address will not be published.