Django如何通过字段名字符串动态访问模型ManyToManyField属性
Django动态获取多对多字段关联管理器方法
场景说明
对于定义了名为references的ManyToManyField多对多字段的模型,静态调用关联管理器的可运行代码如下:
res = [] for ref in MyBook.objects.get(id=some_id).references.values("f_name", "l_name"): res.append(ref)
当仅持有多对多字段的名字符串"references",且已经获取到MyBook模型实例时,无法硬编码写.references属性访问关联管理器,需要动态获取对应引用后才能调用values()等查询方法。
已获取模型实例的代码:
my_book_model = MyBook.objects.get(id=some_id)
实现方案
直接使用Python内置的getattr()方法,通过字段名字符串从模型实例上取出对应的关联管理器即可,后续所有管理器方法的调用逻辑和静态写法完全一致。
完整示例代码:
# 动态传入的多对多字段名 field_name = "references" # 需要查询的关联表字段列表,同样支持动态传入 query_fields = ["f_name", "l_name"] my_book_model = MyBook.objects.get(id=some_id) # 动态拿到关联管理器 m2m_manager = getattr(my_book_model, field_name) # 执行查询,和静态调用my_book_model.references.values()效果完全一致 res = list(m2m_manager.values(*query_fields))
补充说明
- 如果传入的字段名在模型上不存在,
getattr()会默认抛出AttributeError,需要做容错的话可以给getattr()传入第三个参数作为默认返回值,例如getattr(my_book_model, field_name, None),拿到返回值后先做空判断再执行后续查询即可 - 该方法通用适用于Django模型上所有通过属性访问的关联对象,包括外键、一对一字段的关联引用,不局限于多对多字段
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

