ITPub博客

首页 > 数据库 > 数据库开发技术 > Django 中的外键处理与分页查询优化

Django 中的外键处理与分页查询优化

原创 数据库开发技术 作者:IT枫斗者 时间:2024-12-23 17:29:41 0 删除 编辑


1. 查询时外键的处理

在 Django 中,模型中可以通过 ForeignKey 来定义外键关联,并通过 on_delete 来决定关联对象删除时的行为:

from django.db import modelsclass ParentModel(models.Model):   name = models.CharField(max_length=100)class ChildModel(models.Model):   name = models.CharField(max_length=100)   parent = models.ForeignKey(ParentModel, on_delete=models.CASCADE)


on_delete 的选项:


CASCADE:

级联删除。外键所指向的对象被删除时,当前对象也会被删除。

PROTECT:

保护模式。如果外键所指向的对象被使用,将无法删除,并抛出异常。

SET_NULL:

设置为空。外键对象删除后,外键字段被设置为 NULL(前提是字段允许为空)。

SET_DEFAULT:

设置默认值。外键对象删除后,外键字段被设置为默认值(前提是字段有默认值)。

SET():

自定义行为。可以传递一个可调用对象,外键对象删除后,调用该函数设置值。

DO_NOTHING:

不采取任何操作,依赖于数据库的行为。


数据库层级的外键约束:


RESTRICT:

限制删除或更新,默认行为。如果子表存在关联记录,父表不能删除或更新。

CASCADE:

父表记录删除或更新时,子表的相关记录同步删除或更新。

SET NULL:

父表记录删除或更新时,子表的外键字段设置为 NULL。

NO ACTION:

类似于 RESTRICT,但更依赖数据库行为。

2. 如何在 Django 中进行分页查询

分页查询是处理大量数据时的重要优化手段。常见的方法包括 LIMIT 和 OFFSET,配合 ORDER BY 子句使用。



1 使用 LIMIT 和 OFFSET


假设要分页获取数据:

SELECT * FROM table ORDER BY id LIMIT 10 OFFSET 20;

以上查询会跳过前 20 行,返回第 21 到 30 行的记录。

然而,随着 OFFSET 值的增大,性能会显著下降,因为数据库需要扫描所有跳过的记录。



2 优化大偏移量分页


基于最大 ID 的分页

在上一页查询的基础上,通过记录最大 ID 来优化下一页查询:
SELECT * FROM table WHERE id > {last_max_id} ORDER BY id LIMIT 10;
这种方式无需扫描跳过的记录,但要求主键(如 ID)是连续的。

子查询优化

利用子查询提前定位页边界,减少扫描:
SELECT *FROM tableWHERE id > (SELECT id FROM table ORDER BY id LIMIT 20, 1)LIMIT 10;


限制最大页数

通过后端限制最多可访问的页数,避免极大 OFFSET 值引发的性能问题。

3. 在 Django 中实现分页

Django 提供了内置分页工具,尤其是在 REST 框架中,分页处理变得更为简洁高效。



示例:分页查询员工数据


模型定义

from django.db import models

class Employee(models.Model): name = models.CharField(max_length=100) position = models.CharField(max_length=50)


使用 Django REST Framework 的分页功能

from rest_framework.pagination import PageNumberPaginationfrom rest_framework.decorators import api_view, permission_classesfrom rest_framework.response import Responsefrom rest_framework.permissions import IsAuthenticatedfrom .models import Employeefrom .serializers import EmployeeSerializerclass CustomPagination(PageNumberPagination):   page_size = 5  # 每页显示 5 条数据   page_size_query_param = 'size'  # 允许用户通过参数调整每页大小@api_view(['GET'])@permission_classes([IsAuthenticated])def employee_list(request):   queryset = Employee.objects.all().order_by('id')   paginator = CustomPagination()   page = paginator.paginate_queryset(queryset, request)   serializer = EmployeeSerializer(page, many=True)   return paginator.get_paginated_response(serializer.data)


访问分页接口

分页默认接口为 ?page=1,可以通过 size 参数调整每页大小:
http://127.0.0.1:8000/api/employees/?page=1&size=10


返回分页结果

REST 框架自动返回分页元数据和结果:
{   "count": 100,   "next": "http://127.0.0.1:8000/api/employees/?page=2",   "previous": null,   "results": [       {"id": 1, "name": "Alice", "position": "Manager"},       {"id": 2, "name": "Bob", "position": "Engineer"},       ...   ]}


小结

外键处理:

通过 on_delete 定义外键行为,结合数据库层面的约束更安全。

分页优化:

大偏移量分页会导致性能问题,可通过基于最大 ID 或子查询的方式优化。

Django 实现:

利用 Django REST Framework 的分页模块可以轻松实现高效分页。

👋 大家好,我是枫哥,一名Java后端开发者!我热衷于探索新技术,并在我的微信公众号上分享关于Java 生态和后端开发的知识。

欢迎关注我的公众号,期待与你一起探讨技术的无穷可能! ” 目前专注于Java技术分享,覆盖春招、秋招、社招和跳槽相关内容,并提供一对一带徒学习服务。

加入 学徒计划,即可享受内推机会和优质资源,签订协议确保就业无忧。

此外,我们还推出了‘Java跳槽网’, 为你的求职之路提供全方位支持,助你快速找到理想工作



—END—



原文作者:IT枫斗者;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论
大家好,我是枫哥,🌟阿里云技术专家、📝资深面试官、🌹Java跳蚤网课堂创始人。技术交流vx:itfdz666,拥有多年一线研发经验,曾就职过科大讯飞、美团网、平安等公司。看面试实战视频可以关注b站号:IT枫斗者–Java面试。需要看技术文章,可以关注CSDN:IT枫斗者。

注册时间:2020-05-13

  • 博文量
    183
  • 访问量
    81326