Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
graphenepython:从Django模型自动生成模式_Python_Django_Graphene Python - Fatal编程技术网

graphenepython:从Django模型自动生成模式

graphenepython:从Django模型自动生成模式,python,django,graphene-python,Python,Django,Graphene Python,我试图从Django模型生成一个石墨烯模式。我试图通过迭代应用程序、模型,然后向生成的模式添加适当的属性来实现这一点 代码如下: registry = {} def register(target_class): registry[target_class.__name__] = target_class def c2u(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([

我试图从Django模型生成一个石墨烯模式。我试图通过迭代应用程序、模型,然后向生成的模式添加适当的属性来实现这一点

代码如下:

registry = {}


def register(target_class):
    registry[target_class.__name__] = target_class


def c2u(name):
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()


def s2p(name):
    s1 = re.sub("y$", "ie", name)
    return "{}s".format(s1)


class AutoSchemaMeta(type):

    def __new__(meta, clsname, superclasses, attributedict):
        new_class = type(clsname, superclasses, attributedict)
        for app_name in new_class.app_models.split(","):
            app_models = apps.get_app_config(app_name.strip()).get_models()
            for model in app_models:
                model_name = model._meta.model_name
                _model_name = c2u(model_name)

                if hasattr(new_class,_model_name):
                    continue
                _node_class = type("{}Node".format(model_name.title()),
                    (DjangoObjectType,),
                    {"Meta":{"model": model, "interfaces": (Node,), "filter_fields": []}})
                register(_node_class)
                setattr(new_class, "all_{}".format(s2p(_model_name)), DjangoFilterConnectionField(_node_class))
                setattr(new_class, _model_name, Node.Field(_node_class))
        print(new_class.__dict__)
        return new_class


class Query(metaclass=AutoSchemaMeta):

    app_models = "app1,app2"
当我运行我的应用程序时,我得到一个异常:

AssertionError:在中找到具有相同名称的不同类型 架构:WorkflowNode,WorkflowNode

事实证明有一个类已经定义为WorkflowNode,我不想重写它。所以现在我一直在寻找已经定义的类


我已经用
if hasattr(新类,\u模型\u名称)按属性名称排除了:continue
但我不想依赖约定,也不想找出所有已在别处定义的
节点
类,如果它们存在,则使用它们,而不是我正在自动创建的类

我尝试了建议的解决方案,但由于很多原因它不起作用,包括与graphene.ObjectType冲突的元类,因此我创建了一个非常有效的解决方案:

您可以为子类ObjectType提供一个ORM模型列表(在我的例子中是SQLAlchemy),它会自动创建模式。如果您需要为任何字段添加额外的筛选选项,唯一要做的就是添加特殊处理


类SQLAlchemyAutoSchemaFactory(graphene.ObjectType):
@静力学方法
定义集合字段和属性(klazz、节点模型、字段目录):
_名称=驼峰到蛇(节点模型)
field_dict[f'all_{(s2p(_name))}']=FilteredConnectionField(node_model)
field_dict[_name]=节点_model.field()
#log.info(f'接口:{node\u model.\u名称\u}')
setattr(klazz,_name,node_model.Field())
setattr(klazz,“all_{}”.format(s2p(_name)),FilteredConnectionField(node_model))
@类方法
def_u_init_子类_与_meta__(
cls,
接口=(),
模型=(),
排除的_模型=(),
默认\u解析器=无,
_meta=无,
**选择权
):
如果不是_meta:
_meta=对象类型选项(cls)
字段=OrderedDict()
对于接口中的接口:
如果issubclass(接口,SQLAlchemyInterface):
SQLAlchemyAutoSchemaFactory.set_字段和属性(cls、接口、字段)
对于排除的_模型中的模型:
如果模型中有模型:
模型=模型[:模型.索引(模型)]+模型[模型.索引(模型)+1:]
可能的_类型=()
对于模型中的模型:
型号\名称=型号。\名称__
_模型名称=骆驼到蛇(模型名称)
如果hasattr(cls,\ U型号\名称):
持续
如果hasattr(cls,“all”{}.format(s2p(_model_name))):
持续
对于接口中的iface:
如果发布类(模型,iface.\u元模型):
模型_接口=(iface,)
打破
其他:
模型_接口=(自定义节点,)
_节点\类=类型(型号\名称,
(SQLAlchemyObject类型,),
{“Meta”:{“model”:model,“interfaces”:model_interface,“only_字段”:[]})
字段[“所有”{}.format(s2p(_model_name))]=FilteredConnectionField(_node_class)
setattr(cls,“all”{}.format(s2p(_model_name)),FilteredConnectionField(_node_class))
fields[\u model\u name]=CustomNode.Field(\u node\u class)
setattr(cls,_模型_名称,CustomNode.Field(_节点_类))
可能的\u类型+=(\u节点\u类,)
如果_meta.fields:
_meta.fields.update(字段)
其他:
_meta.fields=字段
_meta.schema_types=可能的_类型
超级(SQLAlchemyAutoSchemaFactory,cls)。\uuuuu初始化\u子类\u和\uMeta(\uMeta=\uMeta,default\uResolver=default\uResolver,**选项)
@类方法
带过滤器的def resolve_(cls,信息:ResolveInfo,模型:类型[SQLAlchemyObjectType],**kwargs):
查询=模型。获取查询(信息)
对于filter_name,请使用kwargs.items()中的filter_值:
model\u filter\u column=getattr(model.\u meta.model,filter\u name,None)
如果不是型号过滤器列:
持续
如果isinstance(filter_值,SQLAlchemyInputObjectType):
filter\u model=filter\u value.sqla\u model
q=FilteredConnectionField.get\u查询(filter\u model,info,sort=None,**kwargs)
#无检查参数列表
query=query.filter(model\u filter\u column==q.filter\u by(**filter\u value))
其他:
query=query.filter(model\u filter\u column==filter\u value)
返回查询
您可以这样创建查询:

类查询(SQLAlchemyAutoSchemaFactory): 类元: 接口=(接口1、接口2) 模型=(*entities\u表示iface1,*entities\u表示iface2,*其他实体,) 排除的模型=(基础模型适用于基础模型,基础模型适用于基础模型) 创建如下界面:

类接口1(SQLAlchemyInterface):
类元:
名称='IFACE1节点'
模型=IFACE1模型
和SQLAlchemyInterface:

类SQLAlchemyInterface(节点): @类方法 def_u_init_子类_与_meta__( cls, 型号=无, 注册表=无, 仅_字段=(), 排除_字段=(), 连接\字段\工厂=默认\连接\字段\工厂, _meta=无, **选择权 ): _meta=SQLAlchemyInterfaceOptions(cls) _meta.name=f'{cls.\u u name\u_}节点' 自动排除列=排除自动生成的列(模型=模型) 排除\u字段+=自动排除\u列 断言是映射的类(模型)( “您需要在“{}.Meta”中传递一个有效的SQLAlchemy模型,