Django:如何在ModelAdmin初始化阶段定义自定义变量
优化Django Admin自定义字段的HTTP请求效率
你当前的代码中,MemberAdmin的from_ip方法会为每个列表项发起一次HTTP请求,这会导致页面加载效率低下。利用API支持批量获取所有节点列表的特性,我们可以在ModelAdmin初始化时一次性拉取所有节点数据,后续直接在内存中匹配查询,减少HTTP请求次数。
修改后的完整代码
from django.db import models from django.contrib import admin import requests API_SERVER = 'https://someapiserver.com' class Member(models.Model): nodeid = models.CharField(max_length=20, blank=True, null=True, editable=False) authorized = models.BooleanField(default=False) name = models.CharField(max_length=15, blank=False, null=False) assigned_ip = models.CharField(max_length=15, blank=True, null=True, verbose_name='USE IP') def __str__(self) -> str: return self.name class MemberAdmin(admin.ModelAdmin): list_display = ('nodeid', 'name', 'authorized', 'assigned_ip', 'from_ip') def __init__(self, model, admin_site): super().__init__(model, admin_site) # 初始化时一次性拉取所有节点数据 self.peers = [] try: r = requests.get(f'{API_SERVER}/peer') r.raise_for_status() # 触发HTTP错误状态码的异常 self.peers = r.json() except requests.exceptions.RequestException: # 请求失败时保持peers为空列表,避免后续报错 pass def from_ip(self, obj): try: # 从已拉取的列表中匹配对应nodeid的节点 srcData = next(p for p in self.peers if p['id'] == obj.nodeid) return srcData['from_ip'] except StopIteration: # 找不到对应节点时返回Unknown return 'Unknown' except Exception: # 其他异常也返回Unknown return 'Unknown'
关键修改说明
- 重写
__init__方法:在MemberAdmin初始化时调用API批量获取所有节点数据,并存放在实例变量self.peers中。注意必须先调用super().__init__完成父类的初始化逻辑。 - 异常处理:为API请求添加异常捕获,避免请求失败导致Admin页面无法加载;同时在
from_ip方法中用next()替代列表推导式,更高效地找到匹配项,找不到时捕获StopIteration异常返回Unknown。 - 减少HTTP请求:原本每条数据发起一次请求,现在改为页面加载时仅发起一次请求,大幅提升列表页面的加载速度。
内容的提问来源于stack exchange,提问作者Bino Oetomo
相关产品推荐
相关产品推荐

