警醒:django框架MySql limit分页查询机制和多表查询时遇到的坑(使用limit实现真分页和左连接查询)

1、django的models中对象实现limit真分页(网上的paginator都是假分页,数据量大的时候肯定是不行的)

models定义:JobDept是部门表,TUser是用户表

class JobDept(models.Model):
    dept_id = models.IntegerField(primary_key=True)
    dept_name = models.CharField(unique=True, max_length=45, blank=True, null=True)
    dept_parentid = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'job_dept'

class TUser(models.Model):
    user_id = models.AutoField(db_column='USER_ID', primary_key=True)  # Field name made lowercase.
    user_name = models.CharField(db_column='USER_NAME', unique=True, max_length=32)  # Field name made lowercase.
    user_pwd = models.CharField(db_column='USER_PWD', max_length=512)  # Field name made lowercase.
    user_age = models.IntegerField(db_column='USER_AGE', blank=True, null=True)  # Field name made lowercase.
    user_sex = models.IntegerField(db_column='USER_SEX', blank=True, null=True)  # Field name made lowercase.
    user_qq = models.IntegerField(db_column='USER_QQ', blank=True, null=True)  # Field name made lowercase.
    user_cellphone = models.CharField(db_column='USER_CELLPHONE', max_length=20, blank=True, null=True)  # Field name made lowercase.
    user_money = models.FloatField(db_column='USER_MONEY', blank=True, null=True)  # Field name made lowercase.
    user_status = models.IntegerField(db_column='USER_STATUS', blank=True, null=True)  # Field name made lowercase.
    user_pic = models.CharField(db_column='USER_PIC', max_length=128, blank=True, null=True)  # Field name made lowercase.
    user_role = models.IntegerField(db_column='USER_ROLE', blank=True, null=True, default=1)  # Field name made lowercase.

    jobDept= models.ForeignKey(JobDept, db_column='', on_delete=models.CASCADE, blank=True, null=True, to_field='dept_id')  # null=True生成left join
    user_birth = models.DateTimeField(db_column='USER_BIRTH', blank=True, null=True)  # Field name made lowercase.
    user_intro = models.TextField(db_column='USER_INTRO', blank=True, null=True)  # Field name made lowercase.

    # jobDept__dept_id
    # jobDept__dept_name

    class Meta:
        managed = False
        db_table = 't_user'

2、django对mysql的分页查询其实就是使用切片实现的

以下这行代码解决了分页:[startRow:endRow]写在query后面,就是代表分页

result = query.values('user_id', 'user_name', 'user_sex', 'jobDept__dept_name')[startRow:endRow]  # 会生成 LIMIT

以上代码中的'jobDept__dept_name'这个字段解决了多表联查,jobDept是models中的外键定义,带__两个下划线关联到外表中的列,注意,如果是左连接,一定要在model的声明中,将外键列允许为null,会生成左连接查询

pageSize = 10
	currentPage = 1
	query = TUser.objects
    if user.user_name:
        query = query.filter(user_name__contains=user.user_name)
    if user.user_sex:
        query = query.filter(user_sex=user.user_sex)
        pass

    startRow =  (currentPage - 1)*pageSize
    endRow  = currentPage*pageSize
    result = query.values('user_id', 'user_name', 'user_sex', 'jobDept__dept_name')[startRow:endRow]  # 会生成 LIMIT 2 OFFSET 1

    counts = query.count()

    totalPage = 0
    if(counts%pageSize == 0):
        totalPage = counts//pageSize
    else:
        totalPage = counts // pageSize + 1
        pass

3、生成的SQL语句:左连接和limit分页

(0.010) b'SELECT `t_user`.`USER_ID`, `t_user`.`USER_NAME`, `t_user`.`USER_SEX`, `job_dept`.`dept_name` FROM `t_user` LEFT OUTER JOIN `job_dept` ON (`t_user`.`jobDept_id` = `job_dept`.`dept_id`)  LIMIT 10'; args=()

发布了34 篇原创文章 · 获赞 54 · 访问量 5022

猜你喜欢

转载自blog.csdn.net/nosprings/article/details/102950859