python - 如何在没有构造函数的情况下在 Python 中动态添加自定义类变量
问题描述
如何在不调用构造函数的情况下将类变量动态添加到 Python 类中?在自定义 Django 石墨烯中继节点过滤器中添加自定义查询字段时,这是必需的。
在下面的示例代码中,is_controller
类变量是静态定义的。如何在不使用类外的构造函数或代码的情况下动态生成 BooleanFilter 的变量名称和参数?
这是运行 GraphQL 查询所必需的,例如allSiteEntities(is_controller: true) { ... }
class SiteEntityFilter(FilterSet):
"""Filter for SiteEntityNode that includes component filters"""
is_controller = BooleanFilter(
field_name=controller_component, lookup_expr="isnull", exclude=True
)
class Meta:
model = SiteEntity
fields = {
"site": ["exact"],
"name": ["exact", "icontains", "istartswith"],
"modified_at": ["exact", "gt", "lt"],
}
class SiteEntityNode(DjangoObjectType):
class Meta:
model = SiteEntity
filterset_class = SiteEntityFilter
fields = [
"id",
"site",
"name",
"controller_component",
"created_at",
"modified_at",
]
interfaces = (relay.Node,)
解决方案
通过将动态数据添加到设置中,可以将过滤器和字段动态添加到 GraphQL 查询中。问题是没有调用构造函数,这就是为什么__init__()
不能使用函数并且setattr()
在类定义之后也不起作用的原因。但是,在使用locals()
时可以添加也被 Graphene Relay 接口代码拾取的类变量。
自定义过滤器对于检查是否存在具有用户友好名称的反向 ForeignKey 很有用。
# my_project/settings.py
SITE_ENTITY_COMPONENTS = [
"controller_component",
"peripheral_component",
"hydroponic_system_component",
"water_cycle_component",
]
# my_app/graphql.py
class SiteEntityFilter(FilterSet):
"""Filter for SiteEntityNode that includes component filters"""
for component in settings.SITE_ENTITY_COMPONENTS:
# controller_component --> is_controller
attribute_name = f"is_{component.split('_component')[0]}"
locals()[attribute_name] = BooleanFilter(
field_name=component, lookup_expr="isnull", exclude=True
)
class Meta:
model = SiteEntity
fields = {
"site": ["exact"],
"name": ["exact", "icontains", "istartswith"],
"modified_at": ["exact", "gt", "lt"],
}
class SiteEntityNode(DjangoObjectType):
class Meta:
model = SiteEntity
filterset_class = SiteEntityFilter
fields = [
"id",
"site",
"name",
"created_at",
"modified_at",
].extend(settings.SITE_ENTITY_COMPONENTS)
interfaces = (relay.Node,)
推荐阅读
- node.js - 在 Post 请求上接受在查询参数中包含图像数据的大型 URL
- sqlite - 提高 SQLite 查询时间,两个表有外键
- json - 如何定义数据类(JSON/Kotlin)中可能不存在变量?
- javascript - Vuex将状态对象默认设置为状态数组中的对象
- sass - SASS @extend 使用 @use 导入的类
- colors - 后效脚本颜色填充设置值
- python - 如何通过熊猫返回未显示在列中的时间?
- mysql - MySQL 存储过程,INSERT INTO $table
- javascript - 我在哪里将我的 .env 放在 MERN 应用程序的弹性 beanstalk 部署中
- sympy - 如何使用 Sympy 解决具有多个变量的不等式?