当过滤器字符串为空时,如何停止 Graphql + Django-Filters 到 return 所有对象?
How to stop Graphql + Django-Filters to return All Objects when Filter String is Empty?
使用:
- Django 3.x [Django-Filters 2.2.0, graphene-django 2.8.0, graphql-relay 2.0.1]
- Vue 2.x [Vue-Apollo]
我有一个简单的 Birds
Django 模型,其字段如 name
、habitat
并在这些字段上应用了不同的过滤器,例如 icontains
或 iexact
。我的目标是在我的前端 (Vue) 中应用一个简单的搜索字段。到目前为止它是有效的,但是只要这个过滤器值是空的或有空白 (参见示例 3),Graphql return 就是所有对象。
我的第一个方法是在 FrontEnd 上对我的输入值使用某种逻辑,比如当 String 是 Empty/blank 发送 isnull=true
时。但后来我认为 Django 应该首先处理这个问题。
我想这个问题与我的 filters
(参见 Django < relay_schema.py) 或者换句话说我必须在这些过滤器上应用某种逻辑?
此刻我尝试自定义一些 filterset_class
但感觉这可能太多了,也许我错过了什么?所以我在这里问是否有人有一些提示,因此我的问题是:
当过滤器字符串为空时,如何停止 Graphql + Django 过滤器到 return 所有对象?
GraphiQL IDE
Example 1
query {birdsNodeFilter (name_Iexact: "finch") {
edges {
node {
id
name
}
}
}
}
Returns
{
"data": {
"birdsNodeFilter": {
"edges": [
{
"node": {
"id": "QmlyZHNOb2RlOjE=",
"name": "Finch",
"habitat": "Europe"
}
}
]
}
}
}
适合我!
Example 2
query {birdsNodeFilter (name_Iexact: "Unicorns") {
edges {
node {
id
name
habitat
}
}
}
}
Returns
{
"data": {
"birdsNodeFilter": {
"edges": []
}
}
}
那里没有独角兽 - 很好
Example 3
query {birdsNodeFilter (name_Iexact: "") {
edges {
node {
id
name
}
}
}
}
Return
{
"data": {
"birdsNodeFilter": {
"edges": [
{
"node": {
"id": "QmlyZHNOb2RlOjE=",
"name": "Finch",
"habitat": "Europe"
}
},
{
"node": {
"id": "QmlyZHNOb2RlOjI=",
"name": "Bald Eagle",
"habitat": "USA"
}
},
<...And so on...>
不适合我!
Django
relay_schema.py
class BirdsNode(DjangoObjectType):
class Meta:
model = Birds
filter_fields = {
'id': ['iexact'],
'name': ['iexact', 'icontains', 'istartswith', 'isnull'],
'habitat': ['iexact', 'icontains', 'istartswith'],
}
interfaces = (relay.Node, )
class BirdQuery(graphene.ObjectType):
birdConNode = relay.Node.Field(BirdsNode)
birdsNodeFilter = DjangoFilterConnectionField(BirdsNode)
这是我在 GraphiQL 和我的前端 VUE 中工作的解决方案。
我为每个 Filter 添加了一个逻辑到 Birds2Query
和 def resolve_all_birds2
(出于测试目的而不是在所有 Filter 上)。
除此之外,我还添加了一个 ExtendedConnection
用于计数。
注意: 我更改了我之前问题中的 class 名称。
更新:此解决方案适用于 python 方面。但是 apollo client
还提供了 Apollo manager
- 也称为 Dollar Apollo
- 您还可以使用 this.$apollo.queries.tags.skip
属性 作为静态或动态解决方案来启动和停止查询。
relay_schema.py
class ExtendedConnection(Connection):
class Meta:
abstract = True
total_count = Int()
edge_count = Int()
name_check = ""
def resolve_total_count(root, info, **kwargs):
return root.length
def resolve_edge_count(root, info, **kwargs):
return len(root.edges)
class Birds2Node(DjangoObjectType):
class Meta:
model = Birds
filter_fields = {
'id': ['exact', 'icontains'],
'name': ['exact', 'icontains', 'istartswith', 'iendswith'],
}
interfaces = (relay.Node, )
connection_class = ExtendedConnection
class Birds2Query(ObjectType):
birds2 = relay.Node.Field(Birds2Node)
all_birds2 = DjangoFilterConnectionField(Birds2Node)
def resolve_all_birds2(self, info, **kwargs):
# Filtering for Empty/ Blank Values in Filter.Key.Value before returning queryset
if 'name__icontains' in kwargs:
nameIcon = kwargs['name__icontains']
nameIconBool = bool(nameIcon.strip()) # if blanks turns False
if nameIconBool == False: # has blanks
return Birds.objects.filter(name=None)
pass
if 'name__istartswith' in kwargs:
nameIsta = kwargs['name__istartswith']
nameIstaBool = bool(nameIsta.strip()) # if blanks turns False
if nameIstaBool == False: # has blanks
return Birds.objects.filter(name=None)
pass
return
GraphiQL
Blockquote
示例 1
query {allBirds2 (name_Icontains:""){
totalCount
edgeCount
edges {
node {
id
name
habitat
}
}
}
}
过滤器为空时停止 return 所有对象。
{
"data": {
"allBirds2": {
"totalCount": 0,
"edgeCount": 0,
"edges": []
}
}
}
示例 2 有空格和一个字母
query {allBirds2 (name_Icontains:" f "){
totalCount
edgeCount
edges {
node {
id
name
habitat
}
}
}
}
return - 正是我想要的
{
"data": {
"allBirds2": {
"totalCount": 1,
"edgeCount": 1,
"edges": [
{
"node": {
"id": "QmlyZHMyTm9kZTox",
"name": "Finch",
"habitat": "Europe"
}
}
]
}
}
}
使用:
- Django 3.x [Django-Filters 2.2.0, graphene-django 2.8.0, graphql-relay 2.0.1]
- Vue 2.x [Vue-Apollo]
我有一个简单的 Birds
Django 模型,其字段如 name
、habitat
并在这些字段上应用了不同的过滤器,例如 icontains
或 iexact
。我的目标是在我的前端 (Vue) 中应用一个简单的搜索字段。到目前为止它是有效的,但是只要这个过滤器值是空的或有空白 (参见示例 3),Graphql return 就是所有对象。
我的第一个方法是在 FrontEnd 上对我的输入值使用某种逻辑,比如当 String 是 Empty/blank 发送 isnull=true
时。但后来我认为 Django 应该首先处理这个问题。
我想这个问题与我的 filters
(参见 Django < relay_schema.py) 或者换句话说我必须在这些过滤器上应用某种逻辑?
此刻我尝试自定义一些 filterset_class
但感觉这可能太多了,也许我错过了什么?所以我在这里问是否有人有一些提示,因此我的问题是:
当过滤器字符串为空时,如何停止 Graphql + Django 过滤器到 return 所有对象?
GraphiQL IDE
Example 1
query {birdsNodeFilter (name_Iexact: "finch") {
edges {
node {
id
name
}
}
}
}
Returns
{
"data": {
"birdsNodeFilter": {
"edges": [
{
"node": {
"id": "QmlyZHNOb2RlOjE=",
"name": "Finch",
"habitat": "Europe"
}
}
]
}
}
}
适合我!
Example 2
query {birdsNodeFilter (name_Iexact: "Unicorns") {
edges {
node {
id
name
habitat
}
}
}
}
Returns
{
"data": {
"birdsNodeFilter": {
"edges": []
}
}
}
那里没有独角兽 - 很好
Example 3
query {birdsNodeFilter (name_Iexact: "") {
edges {
node {
id
name
}
}
}
}
Return
{
"data": {
"birdsNodeFilter": {
"edges": [
{
"node": {
"id": "QmlyZHNOb2RlOjE=",
"name": "Finch",
"habitat": "Europe"
}
},
{
"node": {
"id": "QmlyZHNOb2RlOjI=",
"name": "Bald Eagle",
"habitat": "USA"
}
},
<...And so on...>
不适合我!
Django
relay_schema.py
class BirdsNode(DjangoObjectType):
class Meta:
model = Birds
filter_fields = {
'id': ['iexact'],
'name': ['iexact', 'icontains', 'istartswith', 'isnull'],
'habitat': ['iexact', 'icontains', 'istartswith'],
}
interfaces = (relay.Node, )
class BirdQuery(graphene.ObjectType):
birdConNode = relay.Node.Field(BirdsNode)
birdsNodeFilter = DjangoFilterConnectionField(BirdsNode)
这是我在 GraphiQL 和我的前端 VUE 中工作的解决方案。
我为每个 Filter 添加了一个逻辑到 Birds2Query
和 def resolve_all_birds2
(出于测试目的而不是在所有 Filter 上)。
除此之外,我还添加了一个 ExtendedConnection
用于计数。
注意: 我更改了我之前问题中的 class 名称。
更新:此解决方案适用于 python 方面。但是 apollo client
还提供了 Apollo manager
- 也称为 Dollar Apollo
- 您还可以使用 this.$apollo.queries.tags.skip
属性 作为静态或动态解决方案来启动和停止查询。
relay_schema.py
class ExtendedConnection(Connection):
class Meta:
abstract = True
total_count = Int()
edge_count = Int()
name_check = ""
def resolve_total_count(root, info, **kwargs):
return root.length
def resolve_edge_count(root, info, **kwargs):
return len(root.edges)
class Birds2Node(DjangoObjectType):
class Meta:
model = Birds
filter_fields = {
'id': ['exact', 'icontains'],
'name': ['exact', 'icontains', 'istartswith', 'iendswith'],
}
interfaces = (relay.Node, )
connection_class = ExtendedConnection
class Birds2Query(ObjectType):
birds2 = relay.Node.Field(Birds2Node)
all_birds2 = DjangoFilterConnectionField(Birds2Node)
def resolve_all_birds2(self, info, **kwargs):
# Filtering for Empty/ Blank Values in Filter.Key.Value before returning queryset
if 'name__icontains' in kwargs:
nameIcon = kwargs['name__icontains']
nameIconBool = bool(nameIcon.strip()) # if blanks turns False
if nameIconBool == False: # has blanks
return Birds.objects.filter(name=None)
pass
if 'name__istartswith' in kwargs:
nameIsta = kwargs['name__istartswith']
nameIstaBool = bool(nameIsta.strip()) # if blanks turns False
if nameIstaBool == False: # has blanks
return Birds.objects.filter(name=None)
pass
return
GraphiQL Blockquote
示例 1
query {allBirds2 (name_Icontains:""){
totalCount
edgeCount
edges {
node {
id
name
habitat
}
}
}
}
过滤器为空时停止 return 所有对象。
{
"data": {
"allBirds2": {
"totalCount": 0,
"edgeCount": 0,
"edges": []
}
}
}
示例 2 有空格和一个字母
query {allBirds2 (name_Icontains:" f "){
totalCount
edgeCount
edges {
node {
id
name
habitat
}
}
}
}
return - 正是我想要的
{
"data": {
"allBirds2": {
"totalCount": 1,
"edgeCount": 1,
"edges": [
{
"node": {
"id": "QmlyZHMyTm9kZTox",
"name": "Finch",
"habitat": "Europe"
}
}
]
}
}
}