Execute Native SQL in Django and Return Results as Dictionaries
This article explains three ways to run raw SQL in Django, demonstrates why the built‑in extra method is discouraged, shows how to use the raw manager and the low‑level connection cursor, and provides helper functions that return query results as dictionaries for easier processing.
Preface
In this tutorial we explore how to execute native SQL statements within a Django project.
Why Use Native SQL?
Django's ORM covers most use‑cases, but for the remaining 20% you may need direct SQL.
Table Structure
Example model:
class Book(models.Model):
title = models.CharField(verbose_name="书名", max_length=32)
describe = models.TextField(verbose_name="描述")
author = models.CharField(verbose_name="作者", max_length=32)
publisher = models.CharField(verbose_name="出版社", max_length=32)
publisher_date = models.DateField(verbose_name="publisher")The table can be populated via the Django admin.
extra Method
The extra method is deprecated and not recommended.
raw Method
The raw manager allows simple raw queries:
ModelName.objects.raw(sql)
ModelName.objects.raw(sql, [param1, param2])It returns model instances.
True Native SQL with Connection
For completely unbound SQL, import the low‑level connection:
from django.db import connection
def book_list(request):
cursor = connection.cursor()
cursor.execute("select * from app01_book where id=%s", [1])
rows = cursor.fetchall()
print(rows)This returns a list of tuples.
Helper Functions Returning Dictionaries
Two utility functions wrap the cursor logic and convert results to dictionaries.
def query_all_dict(sql, params=None):
"""Return all rows as a list of dicts."""
with connection.cursor() as cursor:
if params:
cursor.execute(sql, params=params)
else:
cursor.execute(sql)
col_names = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
return [dict(zip(col_names, row)) for row in rows]
def query_one_dict(sql, params=None):
"""Return a single row as a dict."""
with connection.cursor() as cursor:
if params:
cursor.execute(sql, params=params)
else:
cursor.execute(sql)
col_names = [desc[0] for desc in cursor.description]
row = cursor.fetchone()
return dict(zip(col_names, row))Use these functions directly in views to obtain results as [{...}, {...}] structures.
Summary
Django offers three ways to run raw SQL: extra (generally useless), raw (works but still tied to the model), and the low‑level connection cursor (most flexible). The helper functions query_all_dict and query_one_dict simplify retrieving results as dictionaries.
Recommendation
Prefer the query_all_dict and query_one_dict utilities for clean, dictionary‑based results.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Crawling & Data Mining
Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
