Django认证与权限体系深度解析:从内置机制到实战踩坑
接手一个新项目或者复盘别人代码的时候我最先翻的往往不是业务逻辑而是settings.py里的认证与权限配置。一个系统的认证权限设计直接决定了它的安全边界也决定了后续功能扩展时是顺滑还是处处踩坑。今天这篇就围绕Django的认证与权限体系从内置机制的原理讲到我实际项目里踩过的坑和处理方案既有可以直接抄的配置也有需要自己消化的设计思路。内容主要面向正在用Django做项目、被登录验证和权限控制折磨过的开发者也适合刚接触Django想系统了解这块的新手。1. 认证与权限这件事Django到底帮我们做了什么先说结论Django自带的django.contrib.auth体系已经覆盖了绝大多数Web项目的基础认证和权限需求而且设计得相当巧妙——它把用户是谁和用户能干什么两件事拆开处理这是整个机制里最值得理解的一点。1.1 拆解Django的认证与权限各层职责Django的认证Authentication负责回答你是谁的问题核心是User模型和密码校验权限Authorization负责回答你能干什么的问题核心是Permission模型和权限校验逻辑。两个概念很容易混淆但实际工作中它们各自独立、又彼此配合。我见过不少新手的误区以为登录成功就万事大吉然后在一个视图中反复写if request.user.is_staff之类的判断。其实Django给了你一套更完整的工具链认证层authenticate()函数负责校验用户名和密码login()负责把认证状态写入sessionlogout()负责清理。权限层user.has_perm()判断用户是否拥有某个权限permission_required装饰器和PermissionRequiredMixin做视图级别的拦截。数据层UserGroup用户与组的关联和User_permissions用户专属权限是权限的持久化存储。这套设计的核心思想是尽量少的重复校验代码。你把权限配置好框架自动帮你拦截而不是在每个视图里手写判断逻辑。1.2 为什么内置的AbstractUser往往够用但你需要知道它的边界django.contrib.auth.models.User内置了用户名、密码、邮箱、is_staff、is_superuser、is_active、last_login等字段配合Group模型可以快速实现角色概念。绝大多数初、中级项目用AbstractUser覆写一个自定义用户模型就够了。但内置模型有几个明显边界项目规模上来之后会遇到手机号登录、邮箱登录这类非用户名的认证方式需要额外处理。用户表需要关联业务字段如手机号、头像、部门时需要继承AbstractUser扩展。行级权限数据级权限内置机制不支持需要引入第三方或自己写。所以我个人的建议是新项目从第一天起就用自定义用户模型继承AbstractUser哪怕你现在只需要用户名密码。原因很简单——Django的迁移系统一旦给auth.User建好关联表中途再切换用户模型非常痛苦基本上是要删库重来的级别。这个坑我在实际项目里见过不止一次。2. 认证机制的核心细节模型、密码与认证后端2.1 自定义用户模型的设计与实操步骤如果你决定继承AbstractUser第一步是在settings.py里指定AUTH_USER_MODEL并且必须在第一次migrate之前设置好。# settings.py AUTH_USER_MODEL accounts.User# accounts/models.py from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): # 手机号作为额外的登录凭证 phone models.CharField(max_length11, uniqueTrue, blankTrue, nullTrue) department models.CharField(max_length50, blankTrue, nullTrue) def __str__(self): return f{self.username} ({self.phone or 未绑定})这里有个容易踩的坑如果你在AbstractUser上新增了uniqueTrue的字段必须设置blankTrue或者default否则后台创建用户时会强制校验导致超级用户都创建不出来。phone字段因为不一定每个人都有所以blankTrue, nullTrue是安全选择但uniqueTrue结合nullTrue在MySQL里允许有多条NULL记录这一点要记住。继承AbstractUser后Django的认证、权限、createsuperuser命令等机制全部自动复用。你不需要写任何额外的认证逻辑User.objects.create_user、login_required这些照常工作。2.2 密码哈希与验证流程知道这些你才不会把自己锁在门外一个常见的疑问是Django的密码为什么在数据库里存的是那么怪的一串字符拿pbkdf2_sha256$开头然后是一堆随机字符串。其实格式是算法$迭代次数$盐$哈希值每次登录时Django会根据存储的盐再做一次哈希对比。默认的密码哈希器配置是PASSWORD_HASHERS在Django 4.0之后默认支持PBKDF2等算法。除非有合规要求一般不需要动它。但有一个场景需要注意如果你要做单点登录或对接第三方认证往往会拿到一个明文密码比如从旧系统迁移过来的这时不要直接用User.objects.create()创建用户而是要用user.set_password()。原因很简单set_password()才会走哈希流程直接赋值的话Django会把字符串当哈希值解析你之后永远无法用这个密码登录。# 错误示范密码以明文方式存入了数据库 User.objects.create(usernamealice, passwordmypassword123) # 正确做法 user User(usernamealice) user.set_password(mypassword123) user.save()认证流程本身走的是ModelBackend它会用UserModel.objects.get(usernameusername)查出用户再调用user.check_password(password)做哈希对比。你可以在自定义认证后端里覆写这个查表逻辑实现手机号登录from django.contrib.auth.backends import ModelBackend from django.contrib.auth import get_user_model class PhoneBackend(ModelBackend): def authenticate(self, request, usernameNone, passwordNone, **kwargs): UserModel get_user_model() try: # 允许手机号或用户名任一方式登录 user UserModel.objects.get(phoneusername) if username.isdigit() else UserModel.objects.get(usernameusername) except UserModel.DoesNotExist: return None if user.check_password(password) and self.user_can_authenticate(user): return user return None然后在settings.py中注册这个后端AUTHENTICATION_BACKENDS [ accounts.backends.PhoneBackend, django.contrib.auth.backends.ModelBackend, # 保留默认后台登录能力 ]后端的顺序很重要Django会按顺序尝试每个后端任何一个返回了User对象就停止。所以请把自定义后端放前面ModelBackend放后面作为兜底。提示自定义认证后端写完后记得在authenticate()里最后调用一下self.user_can_authenticate(user)这个方法会校验is_active字段否则你可能会放行被禁用的用户。2.3 登录视图实现session认证的完整链路我们来看一个最简单的登录视图实现以及每个步骤背后的意图from django.contrib.auth import authenticate, login from django.shortcuts import render, redirect def login_view(request): if request.method POST: username request.POST.get(username) password request.POST.get(password) user authenticate(request, usernameusername, passwordpassword) if user is not None: login(request, user) # 写入session更新last_login return redirect(dashboard) else: return render(request, login.html, {error: 用户名或密码错误}) return render(request, login.html)这里最核心的是login()函数。它做了三件事把用户ID写入request.session、调用user.get_session_auth_hash()生成会话哈希用于防篡改、调用user.last_login的更新逻辑可配置。这也是为什么你在登录后修改了密码旧session会失效——因为get_session_auth_hash()依赖于密码哈希密码变了哈希就变了服务端校验不通过。如果项目需要登录后跳回用户原本访问的页面可以用?next参数def login_view(request): ... if user is not None: login(request, user) next_url request.POST.get(next) or request.GET.get(next) return redirect(next_url or dashboard)但要警惕开放重定向问题next参数不能直接当跳转地址用最好校验urlparse后的域名是否在本站内否则恶意用户可以构造一个nexthttps://evil.com绕过。3. 权限系统的运作机制与实操配置3.1 内置权限模型的底层逻辑Model级权限怎么生成Django的权限设计核心是每个模型三个权限add_模型名、change_模型名、delete_模型名。这三个权限在模型执行首次migrate时自动创建到auth_permission表里。权限本身绑定在ContentType上ContentType是Django用来追踪哪个app下有哪些模型的框架层应用。所以你在控制台能看到权限的代号是应用名.权限codename比如blog.add_post、blog.change_post。has_perm()的校验链路是这样的如果用户是is_superuser直接返回True然后看用户自己的user_permissions里有没有这个权限再看用户所属所有组Group的permissions里有没有最后Django 2.1之后还支持通过信号机制让第三方应用比如django-guardian插队追加对象权限判断。这个链路看起来简单但理解透了对排查问题非常有帮助——很多权限失效的问题就是配到了用户身上而不是组上或者在多后端混用时顺序出了问题。3.2 PermissionRequiredMixin与装饰器视图拦截的正确姿势视图层面拦截权限推荐的方式是PermissionRequiredMixin类视图和permission_required装饰器函数视图。举个例子from django.contrib.auth.mixins import PermissionRequiredMixin from django.views.generic import ListView from .models import Article class ArticleListView(PermissionRequiredMixin, ListView): model Article permission_required blog.view_article # 注意Django 2.1 有view权限 raise_exception True # 无权限时直接403而不是跳登录页这里要特别提一下view权限。Django 2.1之前模型只自动生成add/change/delete三个权限之后才新增了view权限。如果你在迁移历史比较老的项目里发现can_view权限不存在多半是模型创建时的迁移没有刷新——需要手动生成一个迁移来补权限或者重新跑migrate时不要跳过auth应用。还有一个细节permission_required可以是元组比如(blog.view_article, blog.change_article)此时需要用户同时拥有所有权限。如果是任一权限即可的场景需要自己写逻辑内置装饰器不支持OR语义。3.3 自定义权限与Group的玩法把权限做成角色实际项目中光有默认的三个增删改查权限是不够的。比如发布文章这个动作在业务上属于编辑角色代码上并没有一个can_publish的字段。Django的做法是在Meta里用permissions属性定义自定义权限class Article(models.Model): title models.CharField(max_length200) status models.CharField(max_length10, choices[ (draft, 草稿), (published, 已发布) ]) class Meta: permissions [ (can_publish, 可以发布文章), (can_review, 可以审核文章), ]执行makemigrations和migrate后auth_permission表里就会多出blog.can_publish和blog.can_review两条记录。你可以通过后台把它们分配给某个Group那么这个组的所有成员就具备了对应能力。这样权限管理就变成了给用户分角色而不是给用户数不清的权限开关运营同事操作起来也轻松很多。3.4 对象级权限当能看所有文章和只能看自己的文章同时存在内置的model级权限有一个硬伤它只能控制某个类型的数据能不能操作不能控制哪一行能操作。比如部门经理可以看本部门所有项目普通员工只能看自己参与的项目——这种场景内置机制做不到。常见的落地方案有三种我按推荐度排序引入django-guardian。它实现了对象级权限模型本质上是在ObjectPermission表里记录某用户/组对某对象有某权限。使用体验是user.has_perm(blog.view_article, obj)。配置量不大迁移时也就多几个表。在QuerySet上手动过滤。这也是最直接简单的方案适用场景是权限规则比较固定class ArticleQuerySet(models.QuerySet): def visible_to(self, user): if user.is_superuser: return self.all() if user.has_perm(blog.view_all_articles): return self.all() return self.filter(authoruser)用中间件在视图层做二次过滤。适合无法大改模型的旧项目但不推荐新项目用——逻辑藏得太深新人接手会非常痛苦。选择对象级权限方案时需要想清楚一点你到底是数据归属权还是操作权。前者谁能看什么数据用QuerySet过滤最顺手后者谁能处理某条数据用guardian更干净。两个混在一起时我建议以QuerySet过滤为主guardian只做例外情况的补充。4. 从认证到APIDRF环境下的权限处理4.1 前后端分离项目中的Token认证与Session认证之争很多新手在做前后端分离时会下意识地认为Session认证过时了直接上JWT。但其实Django原生的Session认证配合DRF的SessionAuthentication完全能扛住同域下的前后端分离项目而且安全模型简单得多——服务端可控。什么时候需要换Token/JWT典型场景是你有多个客户端Web/App/小程序、有第三方开放API、或者需要无状态认证来支撑水平扩展。这些场景下djangorestframework-simplejwt是事实标准。# settings.py REST_FRAMEWORK { DEFAULT_AUTHENTICATION_CLASSES: [ rest_framework_simplejwt.authentication.JWTAuthentication, rest_framework.authentication.SessionAuthentication, ], DEFAULT_PERMISSION_CLASSES: [ rest_framework.permissions.IsAuthenticated, ], }保留SessionAuthentication有个实际好处你在DRF的浏览页面调试接口时可以借用Django后台的登录态不需要每次手动贴Token。生产环境如果不需要可以去掉。4.2 自定义权限类与DRF的action级权限控制DRF的权限体系是建立在Django权限模型之上的。通常我们要做的两件事第一件事把Django的model权限翻译成DRF的接口权限。比如只有blog.can_publish的用户才能调用发布接口from rest_framework.permissions import BasePermission class CanPublishPermission(BasePermission): def has_permission(self, request, view): return request.user.has_perm(blog.can_publish)第二件事用has_object_permission来控制对象级操作。这个方法和上面说的对象级权限思路一致只是挂在DRF视图上class IsOwnerOrReadOnly(BasePermission): def has_object_permission(self, request, view, obj): if request.method in SAFE_METHODS: # GET/HEAD/OPTIONS 放行 return True return obj.author request.user写DRF权限类时有个常见坑has_permission控制的是列表和新建接口has_object_permission控制的是详情和修改删除接口。如果你忘了实现has_object_permission默认是返回True的——也就是说你的IsOwnerOrReadOnly只会拦住没登录的人而挡不住登录了但不是作者的人。我自己在这个地方栽过跟头后来干脆在基类里默认覆写has_object_permission为False强制自己每个权限类都显式声明。5. 常见认证权限问题与排查心得5.1 用户已登录但权限不够八成是session和权限缓存的问题这是最经典的一个问题。症状是用户明明在后台配置了权限刷新页面依然403。我先讲排查路径第一步确认权限确实分配给了用户或用户所属组。注意组的权限不会立刻复制到用户的历史session里——严格来说权限每次请求都查库所以不是缓存问题而是你分配错了对象。第二步确认自定义用户模型没有覆写has_perm。一旦覆写就绕过了框架默认链路你写的每一个逻辑分支都要自己负责。第三步看AUTHENTICATION_BACKENDS有没有多个后端。多个后端时只要任何一个后端返回True用户就有权限。如果你同时保留了某个宽松的后端它可能把你本来想拦截的权限给放行了。还有一个很容易被忽略的问题Django的后台request.user和我们接口里的request.user不是同一个对象实例如果你在中间件里修改了user的属性比如动态塞了一个角色字段这个改动在DRF视图里不一定生效。解决方案是把逻辑放到property里实时计算而不是存到实例属性。5.2 删除对象失败、权限不足的常规排查Web开发中有很多权限不足的报错不全是Django层面的。比如Windows系统里常见的你需要来自administrators的权限才能删除文件这跟Django毫无关系——那是文件系统ACLAccess Control List的问题。这里顺便帮大家区分一下各类权限报错的语义报错场景原因层次解决思路Django 403 Forbidden应用层权限检查has_perm/DRF权限类Windows删除文件提示需要administrators权限文件系统ACL修改文件所有者或ACL条目不是Web开发者的问题Docker容器内挂载目录提示permission denied系统用户/组权限或SELinux调整容器USER或目录UID/GID数据库执行INSERT/UPDATE报permission denied数据库账号权限检查数据库授权SQL遇到这类问题先判断报错发生在哪一层别在一个方向死磕。这是我在跨技术栈排查时最深的体会。5.3 常见问题速查表整理一份我实际开发中整理过的排查清单登录失败但密码正确检查User.is_active是否为True。ModelBackend.authenticate默认会拒绝非活动用户错误信息和密码错误一样故意混淆防止探测。修改密码后旧会话依然有效Django默认允许密码修改后旧会话保留到SESSION_COOKIE_AGE过期。如果你希望改密即踢下线需要在视图里调用request.session.flush()或配置SESSION_COOKIE_AGE目前没有开关直接实现。has_perm在模板中无效模板里{{ perms }}是懒加载对象需要确认模板上下文处理器已经启用。在DRF的renderer渲染模板时默认不走Django模板上下文处理器需要手动传。自定义权限在migrate后没出现检查是否在正确的模型Meta里定义了permissions。权限是挂在ContentType上的如果你给抽象基类写Meta权限不会生效。is_superuser和is_staff混淆is_staff只是能进后台不直接表示所有权限is_superuser在权限校验时通配全部。两个字段互相独立想给一个用户后台访问权又不想让他看到特定菜单时这俩要分开配。5.4 一次真实的对象级权限踩坑实录去年做一个项目管理系统需求是项目经理能看自己项目的全部数据普通成员只能看自己有待办的事项。我一开始图省事在列表视图中这么写class TaskListView(ListView): def get_queryset(self): if self.request.user.has_perm(project.manage): return Task.objects.filter(project__managerself.request.user) return Task.objects.filter(assigneeself.request.user)看起来挺对问题出现在一个细节项目经理创建了一个任务后又把任务指派给了普通成员。这时普通成员在列表里能看到这个任务因为assignee是他但每次点开详情都会因为详情视图的get_object里也查了一次权限……class TaskDetailView(DetailView): def get_object(self, querysetNone): obj super().get_object(queryset) # 这里只有项目经理能看但普通成员已经拿到列表入口了 if not (obj.project.manager self.request.user or obj.assignee self.request.user): raise PermissionDenied return obj结果就是列表可见、详情403用户反馈极差。真正的问题是列表和详情用的两套过滤逻辑不一致。后来我把权限判断统一成一个TaskQuerySet.visible_to(user)方法列表和详情都用同一个方法过滤才彻底解决。这个案例说明一个道理对象级权限一定要收敛到一个地方维护最好挂在QuerySet上列表、详情、导出、统计等所有入口都走同一个方法。权限逻辑一旦分散就会出现列表能看、详情不能看这种让用户懵掉的状态。6. 高质量权限体系的经验总结与扩展方向做认证权限这套东西越久越觉得它的核心其实不是技术而是职责划分。你在配置权限之前一定要拉上产品和技术一起把角色定义清楚而不是边写代码边发明角色。前期角色写得越乱后期权限配置就越灾难。在我维护过的项目里表现最好的权限设计通常具备这么几个特征权限点在模型层就声明好而不是在视图层临时造。需要新增权限时先改模型Meta再写视图判断。用户尽量通过Group拿权限而不是直接挂user_permissions。直接挂在用户上的权限后期审计非常难查要搞清楚谁给了谁什么权限只能在数据库里翻。行级权限统一收敛在QuerySet里凡是列表视图就走同一个过滤方法。后面接报表、接导出、接API都复用。权限校验的报错信息要可读。403页面至少要告诉用户你缺了哪个权限代号不然运营同事截个图过来你连日志都懒得查。这里也顺手推荐几个生态组件都属于可以按需引入的成熟方案django-guardian负责对象级权限djangorestframework-simplejwt提供JWT认证能力django-axes可以限制登录失败次数防暴力破解django-cors-headers用来处理跨域。不过我的原则是能不用第三方的就尽量不用Django内置的认证权限足够撑起大部分业务第三方的价值主要是解决特殊场景引入之前先想清楚是不是真的需要那个功能。最后分享一个我处理认证权限问题时用的小技巧在本地调试时写一个临时的单元测试来打印某个用户的所有权限排错效率极高from django.test import TestCase from django.contrib.auth import get_user_model class PermissionDebugTest(TestCase): def test_print_permissions(self): user get_user_model().objects.get(usernamealice) # 输出全局权限 print(全局权限:, list(user.get_all_permissions())) # 输出所属用户专属权限 print(专属权限:, list(user.user_permissions.values_list(codename, flatTrue))) # 输出组权限 print(组权限:, list(user.groups.values_list(permissions__codename, flatTrue)))这个小工具能帮你一眼看清权限到底在哪个层级生效了。很多人排查权限问题靠猜其实把这三行打印出来问题就变成了这个权限该放到哪一层的结构问题而不是代码哪里写错了的玄学问题了。

相关新闻

Python BoundedSemaphore 有界信号量详解

Python BoundedSemaphore 有界信号量详解

Python BoundedSemaphore 有界信号量详解一、Python BoundedSemaphore 有界信号量详解1、 引言2、信号量基础回顾2.1、 什么是信号量2.2、 普通 Semaphore 的问题3、 BoundedSemaphore 的原理3.1、 有界约束3.2、 源码实现4、基本用法4.1、 标准「获取-释放」模式4.2、 使用上下…

2026/10/10 6:01:46 阅读更多 →
埃拉托斯特尼筛法全解析:从求第N个质数到工程级优化

埃拉托斯特尼筛法全解析:从求第N个质数到工程级优化

1. 从一道经典问题说起:求第 N 个质数到底难在哪如果你是刚接触算法不久,或者刷题时卡在“求第 100000 个质数”这种题目上,那你一定体会过那种“明明思路很简单,但一跑就超时”的挫败感。质数判定本身不复杂,教科书里…

2026/10/10 6:01:46 阅读更多 →
更新至2026年全球地缘政治风险指数GPR数据(日度+月度)

更新至2026年全球地缘政治风险指数GPR数据(日度+月度)

更新至2026年全球地缘政治风险指数GPR数据(日度月度) 1、时间:日度数据(1985.1.1-2026.5.18)、月度数据(1900.1-2026.4) 2、指标: 日度:DAY、Number of articles (10 recent newspapers, 198…

2026/10/10 6:01:46 阅读更多 →

最新新闻

StackEdit v5.14.10部署实战:打造离线Markdown写作环境

StackEdit v5.14.10部署实战:打造离线Markdown写作环境

简介:StackEdit v5.14.10 的免安装部署包,面向需要私有化 Markdown 编辑环境的开发者、博主、学生与协作团队。核心是纯前端浏览器编辑器,无需安装桌面软件,将静态资源放入 Apache 或 Nginx 服务器即可通过任意设备访问使用&#…

2026/10/10 6:36:58 阅读更多 →
OpenClaw 太难装了?试试 LangTARS:一行命令部署 + WebUI 管理面板,还能接入 Dify/Coze,TaoToken 统一 Key 打通多模型

OpenClaw 太难装了?试试 LangTARS:一行命令部署 + WebUI 管理面板,还能接入 Dify/Coze,TaoToken 统一 Key 打通多模型

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 6:36:58 阅读更多 →
毕业论文神器!2026年实力出众的专业AI论文写作工具

毕业论文神器!2026年实力出众的专业AI论文写作工具

2026年AI论文写作工具已从“内容生成”进化为具备学术合规性与智能优化能力的专业平台,核心评价维度涵盖文献真实性、格式合规性、长文本逻辑、查重降重、AIGC合规等关键指标。本次测评覆盖6款主流工具,测试场景包括中文/英文论文撰写、全流程与专项功能…

2026/10/10 6:36:58 阅读更多 →
论文结论怎么写?工具按环节配齐

论文结论怎么写?工具按环节配齐

很多同学写论文,正文洋洋洒洒上万字,到了结论却草草收场:要么把摘要换个说法重抄一遍,要么堆几句"本研究具有一定参考价值"的空话。这种"结论写不实"的问题,从本科到博士几乎都会遇到。问题往往不…

2026/10/10 6:36:58 阅读更多 →
文献综述从检索到成文怎么闭环?一篇讲透全流程

文献综述从检索到成文怎么闭环?一篇讲透全流程

写文献综述常让人头疼的,往往不是"不会写",而是检索和成文两条线各走各的:检索时漫无目的,成文时发现文献和观点对不上,只好推倒重来。这篇把检索、筛选、阅读、成文四个环节串成一条完整闭环,一…

2026/10/10 6:36:58 阅读更多 →
Java集合框架底层原理与性能优化:从ArrayList到HashMap

Java集合框架底层原理与性能优化:从ArrayList到HashMap

Java里的集合框架,很多开发者从学习第一天就开始用,ArrayList存数据、HashMap做缓存,写着写着就成了肌肉记忆。但真正问你几个问题——ArrayList扩容到底怎么扩的?HashMap在JDK 8里引入红黑树是为什么?遍历的时候删元素…

2026/10/10 6:35:57 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →