Django使用原生SQL语句的两种方式

一、Manager.raw(raw_queryparams=Nonetranslations=None)

此方法接受原始SQL查询,执行该查询,然后返回django.db.models.query.RawQuerySet实例。可以像普通QuerySet一样迭代此RawQuerySet实例以提供对象实例。

例如:

class Person(models.Model):
    first_name = models.CharField(...)
    last_name = models.CharField(...)
    birth_date = models.DateField(...)

>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
...     print(p)
John Smith
Jane Jones

注意:原生sql语句中使用的是数据库中的实际表名,而不是model名。

使用raw()的几大特点:

  • 自动将查询中的字段映射到模型上的字段,查询中字段的顺序无关紧要。下面两种结果相同。
>>> Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person')
...
>>> Person.objects.raw('SELECT last_name, birth_date, first_name, id FROM myapp_person')
...
  • 支持对结果集的索引。
first_person = Person.objects.raw('SELECT * FROM myapp_person')[0]

'''但是,索引和切片不是在数据库级别执行的。'''
'''如果数据库中有大量的Person对象,则在SQL级别限制查询会更有效'''

first_person = Person.objects.raw('SELECT * FROM myapp_person LIMIT 1')[0]
  • 传参数

如果需要执行参数化查询,则可以对raw()使用params参数。

lname = 'Doe'
Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])

params是参数的列表或字典,您将在查询字符串中将%s占位符用于列表,或将%(key)s占位符用于字典(其中键由字典键替换),无论您的数据库引擎如何。此类占位符将被params参数中的参数替换。

注意:SQLite后端不支持字典参数。使用此后端,您必须将参数作为列表传递。

警告1:

  • 不要在原始查询中使用字符串格式,也不要在SQL字符串中引用占位符!
# 错误思路1
>>> query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
>>> Person.objects.raw(query)

# 错误思路2(您可能还认为应该这样编写查询(用引号引起来的%s))
>>> query = "SELECT * FROM myapp_person WHERE last_name = '%s'"

使用params参数并且不使用占位符会保护您免受SQL注入攻击。

警告2:

  • 传递给.raw()的SQL语句不做任何检查,Django期望该语句将从数据库中返回一组行,但是不执行任何操作。如果查询不返回行,则将导致(可能是神秘的)错误。
  • 如果要在MySQL上执行查询,请注意,混合类型时,MySQL的静默类型强制可能会导致意外结果。如果在字符串类型的列上查询但具有整数值,MySQL将在执行比较之前将表中所有值的类型强制为整数,例如,如果您的表包含值“ abc”,“ def”,并且您查询WHERE mycolumn = 0,则两行都将匹配。为避免这种情况,请在查询中使用该值之前执行正确的类型转换。

二、直接执行自定义SQL

from django.db import connection

def my_custom_sql(self):
    with connection.cursor() as cursor:
        cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
        row = cursor.fetchone()

    return row

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过以下步骤实现在 Django使用原生 SQL 语句和 Layui 导出数据: 1. 编写原生 SQL 语句,查询需要导出的数据。 2. 在 Django 中执行 SQL 语句,获取查询结果。 ```python from django.db import connection with connection.cursor() as cursor: cursor.execute("SELECT * FROM myapp_mymodel") results = cursor.fetchall() ``` 3. 将查询结果转换为需要导出的数据格式,例如 CSV。 ```python import csv response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="export.csv"' writer = csv.writer(response) for row in results: writer.writerow(row) return response ``` 4. 在前端页面中使用 Layui 提供的数据表格组件实现导出功能。 ```javascript <table class="layui-table"> <thead> <tr> <th>列1</th> <th>列2</th> <th>列3</th> </tr> </thead> <tbody> {% for row in results %} <tr> <td>{{ row.0 }}</td> <td>{{ row.1 }}</td> <td>{{ row.2 }}</td> </tr> {% endfor %} </tbody> </table> <button class="layui-btn" onclick="exportData()">导出数据</button> <script> function exportData() { window.location.href = "{% url 'export_data' %}"; } </script> ``` 在点击“导出数据”按钮时,将发送一个 GET 请求到 Django 后端的导出数据视图函数,在该函数中执行 SQL 查询并将查询结果转换为 CSV 格式,然后通过 HTTP 响应返回给前端页面,实现文件下载的功能。 以上是一个简单的示例,你可以根据实际需求和业务逻辑进行相应的修改和拓展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值