Django admin如何基于verbose_name修改模型对应管理页面URL
解决方案
问题根因
你遇到的URL冲突问题核心原因有3个:
- 所有动态生成的模型类名都是
Stocks,Django Admin生成URL时默认取模型类名小写 + 所属app名作为路径标识,因此所有模型的管理URL完全一致,入口自然指向同一个页面 - 循环内重复定义
StocksAdmin类,后一次循环会覆盖前一次的类定义,仅最后一个表的Admin配置会生效 - 你写的
get_urls方法定义在StocksAdmin类外部,没有绑定到Admin类,因此完全不会执行
修改步骤
1. 重构动态模型生成逻辑,给每个模型分配唯一标识
使用type动态创建模型,为每个模型生成唯一类名,也可以直接指定model_name控制URL中的模型标识:
tables = [f.id for f in StockId.objects.raw( "SELECT TABLE_NAME AS id FROM INFORMATION_SCHEMA.tables WHERE TABLE_NAME LIKE 'my_project_auth_stockid%%'")] table_map = {} for tbl in tables: # 生成唯一模型类名,替换表名中的非法字符 model_class_name = f"Stocks_{tbl.replace('-', '_')}" # 动态创建模型类 Stocks = type( model_class_name, (models.Model,), { "user_id": models.IntegerField(), "product_name": models.CharField(max_length=100), "mrp": models.IntegerField(), "selling_price": models.IntegerField(), "__module__": __name__, # 必须指定模型所属模块,否则Django无法识别 "Meta": type( "Meta", (), { "db_table": tbl, "managed": False, "verbose_name": _(tbl), "verbose_name_plural": _(tbl), # 直接指定model_name为表名,生成的URL会直接使用该值作为模型标识 "model_name": tbl.lower() } ) } ) table_map[tbl] = Stocks
2. 重构Admin注册逻辑
把公共的Admin配置提到循环外定义,避免重复创建类,直接注册即可:
from django.contrib.admin import AdminSite from import_export.admin import ImportExportModelAdmin from my_project_auth.models import * class AllStocksAdmin(AdminSite): site_header = 'All User Stocks' stockadmin = AllStocksAdmin(name="stockadmin") # 公共Admin配置提至循环外,避免重复定义 class BaseStocksAdmin(ImportExportModelAdmin): resource_class = StocksAdminResource list_display = ["product_name"] # 循环注册所有动态模型 for tbl in tables: stockadmin.register(table_map[tbl], BaseStocksAdmin)
可选:完全自定义URL规则
如果你需要URL完全匹配自定义规则,可以重写Admin类的get_urls方法:
class BaseStocksAdmin(ImportExportModelAdmin): resource_class = StocksAdminResource list_display = ["product_name"] def get_urls(self): urls = super().get_urls() # 取当前模型的表名作为URL前缀 custom_urls = [ path( f"{self.model._meta.db_table}/", self.changelist_view, name=f"{self.model._meta.app_label}_{self.model._meta.model_name}_changelist" ) # 其他需要自定义的增删改查路径可在此处添加 ] return custom_urls + urls
内容的提问来源于stack exchange,提问作者Ankit Chaurasia
相关产品推荐
相关产品推荐

