如何仅继承AuthenticationForm为Django Admin登录页添加account_id字段
在Django Admin默认登录模板中添加account_id字段的实现方案
完全可行,无需自定义登录模板,仅通过子类化AuthenticationForm并调整相关代码即可实现需求。以下是具体调整步骤:
1. 完善自定义认证表单
重写clean方法,将account_id字段值传递给认证后端,并处理验证逻辑:
from django.contrib.auth.forms import AuthenticationForm from django import forms from agent.models import Agent class HeliosAuthenticationForm(AuthenticationForm): account_id = forms.ModelChoiceField(queryset=Agent.objects.all(), label="账号ID") def clean(self): cleaned_data = super().clean() user_id = cleaned_data.get("username") # 对应USERNAME_FIELD设置的user_id account_id = cleaned_data.get("account_id") password = cleaned_data.get("password") if user_id and account_id and password: # 调用自定义认证后端验证 self.user_cache = self.authenticate( request=self.request, user_id=user_id, account_id=account_id.id, # 传递主键值 password=password ) if not self.user_cache: raise forms.ValidationError("用户ID、账号ID或密码错误") self.confirm_login_allowed(self.user_cache) return cleaned_data
2. 修正认证后端的get_user方法
Django要求get_user仅接收user_id参数,需结合session存储的account_id来获取用户:
from django.contrib.auth.backends import BaseBackend from .models import HeliosUser class SettingsBackend(BaseBackend): def authenticate( self, request, user_id=None, account_id=None, password=None, **kwargs ): try: user = HeliosUser.objects.get(user_id=user_id, account_id=account_id) except HeliosUser.DoesNotExist: return None if user.check_password(password): # 将account_id存入session,供get_user方法使用 request.session["account_id"] = user.account_id.id return user return None def get_user(self, user_id): try: account_id = self.request.session.get("account_id") return HeliosUser.objects.get(user_id=user_id, account_id=account_id) except HeliosUser.DoesNotExist: return None
3. 确认AdminSite配置正确性
你的现有AdminSite代码已正确指定login_form,只需确保urls.py使用自定义admin_site:
from django.urls import path from .admin import admin_site urlpatterns = [ path("admin/", admin_site.urls), ]
效果验证
启动服务后访问Admin登录页,表单会自动渲染新增的account_id下拉字段,输入user_id、account_id和密码即可完成认证。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

