当前位置: 首页 > 面试题库 >

Django:Paginator +原始SQL查询

墨宜人
2023-03-14
问题内容

我在我的网站上到处都有Django
Paginator,甚至编写了一个特殊的模板标签,以使其更加方便。但是现在我进入一种状态,我需要进行一个复杂的自定义原始SQL查询,没有该状态LIMIT将返回大约100K条记录。

如何在自定义查询中使用Django Pagintor?

我的问题的简化示例:

我的模特:

class PersonManager(models.Manager):

    def complicated_list(self):

        from django.db import connection

        #Real query is much more complex        
        cursor.execute("""SELECT * FROM `myapp_person`""");

        result_list = []

        for row in cursor.fetchall():
            result_list.append(row[0]);

        return result_list


class Person(models.Model):
    name      = models.CharField(max_length=255);
    surname   = models.CharField(max_length=255);     
    age       = models.IntegerField();

    objects   = PersonManager();

我在Django ORM中使用分页的方式:

all_objects = Person.objects.all();

paginator = Paginator(all_objects, 10);

try:
    page = int(request.GET.get('page', '1'))
except ValueError:
    page = 1

try:
    persons = paginator.page(page)
except (EmptyPage, InvalidPage):
    persons = paginator.page(paginator.num_pages)

这样,Django变得非常聪明,并LIMIT在执行查询时将其添加到查询中。但是当我使用自定义管理器时:

all_objects = Person.objects.complicated_list();

所有数据都被选中,然后才对python list进行切片,这非常慢。如何使自定义管理器的行为类似于内置管理器?


问题答案:

特别是看一下Paginator的源代码page()函数,我认为这只是在您这一边实现切片,并将其转换为SQL查询中的相关LIMIT子句的问题。您可能还需要添加一些缓存,但是它开始看起来像QuerySet,因此也许您可以做其他事情:

  • 您可以使用CREATE VIEW myview AS [您的查询]创建数据库VIEW;
  • 为该视图添加Django模型,并添加Meta:managed = False
  • 与其他任何模型一样使用该模型,包括对其查询集进行切片-这意味着它非常适合与Paginator一起使用

(供您参考-我已经使用这种方法很长时间了,即使与VIEWs的复杂多对多关系伪造了m2m中间表。)



 类似资料:
  • 在模型查询API不够用的情况下,你可以使用原始的sql语句。django提供两种方法使用原始sql进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的sql语句。 警告 编写原始的sql语句时,应该格外小心。每次使用的时候,都要确保转义了参数中的任何控制字符,以防受到sql注入攻击。更多信息请参阅防止sql注入。 进行原始查询 r

  • 我正在尝试使用sqlalchemy执行原始sql查询,并想知道什么是“正确”的方法。 我的查询如下(目前): 我不喜欢的是字符串格式和缺乏任何参数处理(你好music_volume引号:-D)。 我试图遵循这个答案: 如何在SQLAlchemy flask应用程序中执行原始SQL 应用我读到的内容后,我的代码片段如下所示: 然而,我得到的错误,mv和ml是不能识别的参数。 如果我把我的代码片段改成

  • 问题内容: 我在控制器的函数中。 因此,从表单中,我得到了一个变量的值,说: 然后,我需要在WHERE语句中嵌入该变量(即它的值)。如果我对值进行硬编码,它将带来正确的结果,但是我已经尝试了各种方法来插入该变量而没有成功。好吧,假设我设法使用了该变量,那么我将不得不研究绑定以避免SQL注入,但是到目前为止,我要说的是,看看该变量是否可以在查询中使用。 我已经试过了,双引号,串联。$ vx。,花括号

  • 问题内容: 我正在尝试使用类似于以下内容的原始sql查询 但是,这似乎在自己的单独事务中运行。因此,它会错过在service方法中之前完成的所有(未提交的)更改。 在当前事务中运行原始sql查询的最佳方法是什么? 问题答案: 上面的代码将创建一个新的连接,从而创建一个新的事务。您可以使用当前的Hibernate会话(注入sessionFactory)在当前事务中执行原始sql,如下所示。

  • 问题内容: 有没有一种方法可以显示执行查询时Django正在运行的SQL? 问题答案: 请参阅文档FAQ:“如何查看Django正在运行的原始SQL查询? ” 包含SQL查询的列表: 查询集还具有包含要执行的查询的属性: 请注意,查询的输出不是有效的SQL,因为: “ Django实际上从未插值参数:它将查询和参数分别发送到数据库适配器,后者执行适当的操作。” 来自Django错误报告#17741

  • 在用户模型中,我定义了关系: 它返回如何获得包括参数的完整查询? 我还定义了与post模型的关系: 如何使用参数查看完整的关系查询?

  • 由于常常使用简单的方式来执行原始/已经准备好的SQL查询,因此可以使用 sequelize.query 函数. 默认情况下,函数将返回两个参数 - 一个结果数组,以及一个包含元数据(受影响的行等)的对象. 请注意,由于这是一个原始查询,所以元数据(属性名称等)是具体的方言. 某些方言返回元数据 "within" 结果对象(作为数组上的属性). 但是,将永远返回两个参数,但对于MSSQL和MySQL

  • Sequelize中有两种查询:使用Model(模型)中的方法查询和使用sequelize.query()进行基于SQL语句的原始查询。 Model查询 1.1 Attributes - 属性与查询字段 1.2 Where - 指定筛选条件 1.3 limit/offset - 分页与限制返回结果数 1.4 查询排序 原始查询 2.1 原始查询方法 2.2 查询参数替换 2.3 参数绑定 1. M