石墨烯sqlalchemy集成过滤器
graphene-sqlalchemy-filter的Python项目详细描述
快速启动
创建一个过滤器并将其添加到Graphene字段。
fromgraphene_sqlalchemy_filterimportFilterableConnectionField,FilterSetclassUserFilter(FilterSet):is_admin=graphene.Boolean()classMeta:model=Userfields={'username':['eq','ne','in','ilike'],'is_active':[...],# shortcut!}@staticmethoddefis_admin_filter(info,query,value):ifvalue:returnUser.username=='admin'else:returnUser.username!='admin'classQuery(ObjectType):all_users=FilterableConnectionField(UserConnection,filters=UserFilter())
现在,我们要创建查询。
{ allUsers ( filters: { isActive: true, or: [ {isAdmin: true}, {usernameIn: ["moderator", "cool guy"]} ] } ){ edges { node { id username } } } }
让我们摇滚吧!
过滤器
filterset类必须继承graphene_sqlalchemy_filter.FilterSet或 你这个类的子类。
元类必须包含sqlalchemy模型和字段。
有三种类型的过滤器:
自动生成的过滤器
classUserFilter(FilterSet):classMeta:model=Userfields={'username':['eq','ne','in','ilike'],'is_active':[...],# shortcut!}
元类必须包含sqlalchemy模型和字段。
自动生成的筛选器必须由fields变量指定。 sqlalchemy模型的关键字字段名、表达式(或快捷方式)的值列表。
允许的筛选器值:'eq','ne','like','ilike', 'regexp','is_null','in','not_in','lt', 'lte','gt','gte','range'。
快捷方式(默认值:[...])将为此添加所有允许的筛选器 sqlalchemy字段的类型。
简单过滤器
classUserFilter(FilterSet):is_admin=graphene.Boolean()@staticmethoddefis_admin_filter(info,query,value):ifvalue:returnUser.username=='admin'else:returnUser.username!='admin'
每个简单过滤器都有一个类变量,该变量作为 使 过滤。
过滤函数接受以下参数:
- info-resolveinfo石墨烯对象
- query-sqlalchemy查询(不用于该筛选器类型)
- value-筛选器的值
返回值可以是任何类型的sqlalchemy子句。这意味着 您可以返回not_(and_(or_(...),...))。
如果不需要自动生成的筛选器,则不需要元类。
需要连接的筛选器
这种类型的过滤器与simple filters相同 但有不同的返回类型。
过滤函数应该返回一个新的sqlalchemy查询和子句 (就像简单的过滤器)。
classUserFilter(FilterSet):is_moderator=graphene.Boolean()@classmethoddefis_admin_filter(cls,info,query,value):membership=cls.aliased(info,Membership,name='is_moderator')query=query.join(membership,and_(User.id==membership.user_id,membership.is_moderator.is_(True),),)ifvalue:filter_=membership.id.isnot(None)else:filter_=membership.id.is_(None)returnquery,filter_
模型别名
函数cls.aliased(info, model, name='...')缓存sqlalchemy aliases 按给定的模型类和名称在查询筛选范围内。它有 一个不同的参数-info(graphene resolveinfo对象)。其他 参数与sqlalchemy.orm.aliased相同。
sqlalchemy将跳过相同的联接。
功能
重命名graphql filter字段
classCustomField(FilterableConnectionField):filter_arg='where'classQuery(ObjectType):all_users=CustomField(UserConnection,where=UserFilter())all_groups=FilterableConnectionField(GroupConnection,filters=GroupFilter())
{ allUsers (where: {isActive: true}){ edges { node { id } } } allGroups (filters: {nameIn: ["python", "development"]}){ edges { node { id } } } }
重命名表达式
classBaseFilter(FilterSet):GRAPHQL_EXPRESSION_NAMES=dict(FilterSet.GRAPHQL_EXPRESSION_NAMES,**{'eq':'equal','not':'i_never_asked_for_this'})classMeta:abstract=TrueclassUserFilter(BaseFilter):classMeta:model=Userfields={'first_name':['eq'],'last_name':['eq']}
{ allUsers (filters: {iNeverAskedForThis: {firstNameEqual: "Adam", lastNameEqual: "Jensen"}}){ edges { node { id } } } }
自定义快捷方式值
classBaseFilter(FilterSet):ALL='__all__'classMeta:abstract=TrueclassUserFilter(BaseFilter):classMeta:model=Userfields={'username':'__all__'}
文件本地化
classBaseFilter(FilterSet):DESCRIPTIONS={'eq':'Полностью совпадает.','ne':'Не совпадает.','like':'Регистрозависимая проверка строки по шлабону.','ilike':'Регистронезависимая проверка строки по шлабону.','regexp':'Регистрозависимая проверка строки по регулярному выражению.','is_null':'Равно ли значение `null`. Принемает `true` или `false`.','in':'Проверка вхождения в список.','not_in':'Проверка не вхождения в список.','lt':'Меньше, чем указанное значение.','lte':'Меньше или равно указанному значению.','gt':'Больше, чем указанное значение.','gte':'Больше или равно указанному значению.','range':'Значение входит в диапазон значений.','and':'Объединение фильтров с помощью ``AND``.','or':'Объединение фильтров с помощью ``OR``.','not':'Отрицание указанных фильтров.',}classMeta:abstract=True
自定义表达式
deftoday_filter(field,value:bool):today=func.date(field)==date.today()returntodayifvalueelsenot_(today)classBaseFilter(FilterSet):# Add expression.TODAY='today'EXTRA_EXPRESSIONS={'today':{# Add the name of the expression in GraphQL.'graphql_name':'today',# Update allowed filters (used by shortcut).'for_types':[types.Date,types.DateTime],# Add a filtering function (takes the sqlalchemy field and value).'filter':today_filter,# Add the GraphQL input type. Column type by default.'input_type':(lambdatype_,nullable,doc:graphene.Boolean(nullable=False)),# Description for the GraphQL schema.'description':'It is today.',}}classMeta:abstract=TrueclassPostFilter(BaseFilter):classMeta:model=Postfields={'created':['today'],'updated':[...]}
{ allPosts (filters: {createdToday: false, updatedToday: true}){ edges { node { id } } } }
自定义列类型
ALLOWED_FILTERS和EXTRA_ALLOWED_FILTERS只影响快捷方式。
如果不使用快捷方式,则可以跳过本节中描述的后续步骤。
classMyString(types.String):passclassBaseFilter(FilterSet):# You can override all allowed filters# ALLOWED_FILTERS = {types.Integer: ['eq']}# Or add new column typeEXTRA_ALLOWED_FILTERS={MyString:['eq']}classMeta:abstract=True