- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在我们的 GraphQL 服务器上使用带有中继的 django-graphene。该实现强加了一个 Global ID requirement在 graphene.relay.Node
类中,覆盖并隐藏了 Django 的 ID 字段。
因此,我可以这样查询:
{
allBatches(id:"QmF0Y2hOb2RlOjE=") {
edges {
node {
id
pk
}
}
}
}
并得到这个响应:
{
"data": {
"allBatches": {
"edges": [
{
"node": {
"id": "QmF0Y2hOb2RlOjE=",
"pk": 1
}
}
]
}
}
}
但是,我失去的是通过对象本身的原始 ID(或 PK)字段进行过滤的能力:
{
allBatches(id:1) {
edges {
node {
id
pk
}
}
}
}
事实上,我根本无法按ID过滤对象。我可以想到两种可能的解决方法:1. 防止 django-graphene-relay 劫持和隐藏 id
字段,可能会强制它使用不同的字段名称,例如 gid
2. 找到一种方法将 pk
作为一个特殊字段包含在内,既可以作为属性也可以在过滤器中使用
我在 1 上没有取得任何进展,因为它似乎 django-graphene
(可能还有中继标准)强加了一个限制,即该字段被称为 id
。我看到 id
已在多个地方用作魔术字符串,并且似乎没有更改字段名称的标准方法。
在 2 上,我可以像这样让属性与 Mixin
一起工作:
class PKMixin(object):
pk = graphene.Field(type=graphene.Int, source='pk')
但是,我无法通过 django-filter
进行过滤,因为 FilterSet
没有声明字段 pk
并因以下错误而中断
'Meta.fields' contains fields that are not defined on this FilterSet: pk
我尝试了以下方法:
class PKFilteringNode(Node):
@classmethod
def get_node_from_global_id(cls, info, global_id, only_type=None):
# So long as only_type is set; if we detect that the global_id is a pk and not a global ID;
# then coerce it to be a proper global ID before fetching
if only_type:
try:
int(global_id)
global_id = cls.to_global_id(only_type._meta.name, global_id)
return super(PKFilteringNode, cls).get_node_from_global_id(info, global_id, only_type)
except ValueError:
pass
return super(PKFilteringNode, cls).get_node_from_global_id(info, global_id, only_type)
现在我可以使用 GraphQL 来执行此操作:
{
batchA: batch(id: "QmF0Y2hOb2RlOjE=") {
id
name
}
batchB: batch(id: 1) {
id
name
}
}
{
"data": {
"batchA": {
"id": "QmF0Y2hOb2RlOjE=",
"name": "Default Batch"
},
"batchB": {
"id": "QmF0Y2hOb2RlOjE=",
"name": "Default Batch"
}
}
}
But I have a fairly strong fear this will break something downstream, at the level of caching perhaps? Also this does not allow filtering by ID still since filtering depends on
DjangoFilterConnectionField
我现在卡住了。我有几个问题:
https://github.com/graphql-python/graphene-django/issues/349
最佳答案
我不确定你是否仍然想要答案,但至少让我试着回答你的问题。如果我的理解有误,请更正。我只是愿意帮忙
实际上 pk
应该是 DetailView
而不是与 filter
一起使用的 ListView
。
requirements.txt
graphene-django==2.7.1
django==3.0.1
django-filter==2.2.0
python==3.8.1
模型.py
from django.contrib.auth import get_user_model
from django.db import models
User = get_user_model()
class Objection(models.Model):
detail = models.TextField(null=True, blank=True)
hidden = models.BooleanField(default=False)
report = models.BooleanField(default=False)
created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='objections',
related_query_name='objection')
nodes.py
import django_filters
import graphene
from graphene import relay
from graphene_django import DjangoObjectType
from multy_herr.objections.models import Objection
class ObjectionFilter(django_filters.FilterSet):
pk = django_filters.NumberFilter(field_name='pk')
class Meta:
model = Objection
fields = [
'pk',
]
class ObjectionNode(DjangoObjectType):
pk = graphene.Field(type=graphene.Int, source='id')
class Meta:
model = Objection
fields = [
'id',
'pk',
'detail',
'hidden',
'report',
]
filter_fields = {
'pk': ['exact'],
'detail': ['icontains', 'istartswith'],
'created_by__name': ['icontains', ],
'hidden': ['exact'],
'report': ['exact'],
}
interfaces = (relay.Node,)
查询.py
import graphene
from graphene import relay
from graphene_django.filter import DjangoFilterConnectionField
from multy_herr.objections.grapheql.nodes import ObjectionNode, ObjectionFilter
from multy_herr.objections.models import Objection
class ObjectionQuery(graphene.ObjectType):
objection = relay.Node.Field(ObjectionNode)
all_objections = DjangoFilterConnectionField(ObjectionNode,
filterset_class=ObjectionFilter)
def resolve_all_objections(self, info, **kwargs):
if info.context.user.is_authenticated is False:
return Objection.objects.none()
return Objection.objects.filter(created_by=info.context.user)
这里我在query
中留了注释以供类比。使用我的 hackish 解决方案 Insomnia
应用程序将用 Unknown argument pk ...
警告我。但是有效
查询
query{
# objection(id: "T2JqZWN0aW9uTm9kZTo1"){
# id
# report
# hidden
# }
allObjections(pk: 5){
edges{
node{
id
pk
hidden
report
}
}
}
}
响应
{
"data": {
"allObjections": {
"edges": [
{
"node": {
"id": "T2JqZWN0aW9uTm9kZTo1",
"pk": 5,
"hidden": false,
"report": false
}
}
]
}
}
}
关于python - 在 Django Graphene Relay 中启用基于 PK 的过滤,同时保留全局 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54328681/
我尝试了解 Django 中的 Graphql 并使用 graphene和 graphene_django . 我的前端可能会使用 Vuejs 和 Apollo 客户端构建。 互联网上的所有教程都是关
我已经实现了 graphql 并且我正在迁移到中继。我已经为每个表创建了一个 uuid,名为“id”。我找到了我的应用程序 this github thread谈到可能会改变规范,但感觉就像一个兔子洞
不确定我设置错了什么,但是当我使用 uvicorn mysite.asgi:application 在 uvicorn 中运行时,我没有得到 graphiql 界面: [32mINFO[0m:
我想将状态字段添加到错误响应中,而不是这样: { "errors": [ { "message": "Authentication credentials were not p
我的 Django 模型中有一个图像字段,我正在尝试从 Graphene 获取图像字段输出的绝对路径。我记得使用 HttpRequest.build_absolute_uri 获取文件/图像字段的绝对
如果这个问题在其他地方得到回答,那么我很抱歉,但是下类后两天,仍然没有雪茄...... 我有一个播放器模型: class Player(models.Model): name = models
我的 Django 模型中有一个图像字段,我正在尝试从 Graphene 获取图像字段输出的绝对路径。我记得使用 HttpRequest.build_absolute_uri 获取文件/图像字段的绝对
我使用 Django 作为后端,使用 graphene-django 作为前端。我是 django 和 graphene 的新手,所以我不确定在这个设置中没有代码重复的情况下实现字段级权限的最佳方法是
我的应用程序有几个多对多关系 带直通型 像这样: class Person(models.Model): name = models.CharField() class Group(model
我想知道如何正确创建用于创建此 Django 模型的突变: class Company(models.Model): class Meta: db_table = 'compa
我使用 django 和 django graphene 来制作 graphql API。 在我的应用程序中,我使用reactJS和react-bootstrap-table 。 React-boot
我目前正在使用 Python-Graphene 为我的 Django 应用程序创建一个 GraphQL 接口(interface)。虽然查询效果很好,但突变 - 不完全是。 成分的模型: class
假设一个类似于此的 Django 模型: class Profile(models.Model): user = models.OneToOneField(User, on_delete=
我使用 graphen-django 构建 GraphQL API。我已成功创建此 API,但无法传递参数来过滤我的响应。 这是我的 models.py: from django.db import
我在 Django 对象类型定义中遇到 get_node 方法的问题。在我的案例中似乎没有调用该方法。 我什至尝试通过在 get_node 方法中暂停执行来使用 pdb 进行调试,但也没有用。 这是我
到目前为止,我可以在不需要 DjangoObjectType 的情况下使用 Graphene。我尽量避免它,因为我不打算离我的 Django 模型类太近。但是我在使用 Graphene 实现 Rela
说我有, class PersonNode(DjangoObjectType): class Meta: model = Person fields = ('f
所以我的模型看起来像 class Abcd(models.Model): name = models.CharField(max_length=30, default=False) d
目前使用graphene-python 和graphene-django(和graphene-django-optimizer)。 收到GraphQL查询后,数据库查询在几分之一秒内成功完成;然而,
每当引发异常时,它们都会记录在控制台中(如果使用了 Sentry,则记录在 Sentry 中)。 许多这些异常(exception)仅旨在向用户显示。例如, django-graphql-jwt ra
我是一名优秀的程序员,十分优秀!