我的工作graphene和graphene-django我有一个问题,一个IntegerField与选择.graphene创建一个Enum,如果值为1,则输出为"A_1"; 如果值为2则为"A_2",依此类推.例:
# model
class Foo(models.Model):
score = models.IntegerField(choices=((1, 1), (2, 2), (3, 3), (4, 4), (5, 5)))
# query
query {
foo {
score
}
}
# response
{
"data": {
"foo": {
"source": "A_1"
}
}
}
Run Code Online (Sandbox Code Playgroud)
我找到了一个转换选择值的函数.
def convert_choice_name(name):
name = to_const(force_text(name))
try:
assert_valid_name(name)
except AssertionError:
name = "A_%s" % name
return name
Run Code Online (Sandbox Code Playgroud)
并assert_valid_name有这个正则表达式:
r'^[_a-zA-Z][_a-zA-Z0-9]*$'
Run Code Online (Sandbox Code Playgroud)
因此,无论以数字开头,它都会将其转换为"A _...".
我怎么能覆盖这个输出?
当使用外部数据库从多个表中获取数据时,使用GraphQL和Django的最佳方法是什么(即,创建一个表示数据的Django模型不会对应于我的数据库中的单个表)?
我的方法是暂时放弃使用Django模型,因为我认为我还没有完全理解它们.(我对Django和GraphQL都是新手.)我已经设置了一个带有连接外部Postgres DB的应用程序的简单项目.我遵循了Graphene Django教程中的所有设置,然后在我意识到我创建的模型是几个表的混合物时遇到了障碍.
我有一个查询,它发送回映射到我的模型中的字段的正确列,但我不知道如何使这成为一个动态连接,以便当我的API被命中时,它查询我的数据库并将行映射到模型我在Django中定义的模式.
我的方法是避免使用模型,并使用Steven Luscher的演讲中展示的更简单的方法:在30分钟内实现Zero to GraphQL.
TLDR;
目标是能够访问我的GraphQL端点,使用我的django.db.connection中的游标对象来获取应该解析为OrderItemTypes的GraphQLList的字典列表(见下文).
问题是,当我使用查询命中以下端点时,我为每个值获取空值:
localhost:8000/api?query={orderItems{date,uuid,orderId}}
Run Code Online (Sandbox Code Playgroud)
收益:
{ "data":{ "orderItems":[ {"date":null, "uuid":null, "orderId":null }, ... ] } }
Run Code Online (Sandbox Code Playgroud)
project/main/app/schema.py
import graphene
from django.db import connection
class OrderItemType(graphene.ObjectType):
date = graphene.core.types.custom_scalars.DateTime()
order_id = graphene.ID()
uuid = graphene.String()
class QueryType(graphene.ObjectType):
name = 'Query'
order_items = graphene.List(OrderItemType)
def resolve_order_items(root, args, info):
data = get_order_items()
# data prints out properly in my terminal
print data
# data does not resolve properly
return …Run Code Online (Sandbox Code Playgroud) 在Graphene Python 中,schema.py当无法访问HttpResponse要设置 cookie的对象时,应该如何设置 cookie?
我当前的实现是通过捕获data.operationName. 这涉及我需要设置 cookie 的操作名称/突变的硬编码。
在views.py中:
class PrivateGraphQLView(GraphQLView):
data = self.parse_body(request)
operation_name = data.get('operationName')
# hard-coding === not pretty.
if operation_name in ['loginUser', 'createUser']:
...
response.set_cookie(...)
return response
Run Code Online (Sandbox Code Playgroud)
有没有更简洁的方法来为特定的 Graphene Python 突变设置 cookie?
我是石墨烯的新手,我有这个:
from django.contrib.auth.models import User
class UserType(DjangoObjectType):
class Meta:
model = User
Run Code Online (Sandbox Code Playgroud)
基本上,使用Django的User类会给我这个错误,因为在使用django User类之前,我使用了自己的User定义并且可以正常工作。为什么使用django身份验证框架中的User类会给我标题中提到的错误:
如果map中的type.name,则在reducer中的文件“ /usr/local/lib/python3.6/site-packages/graphql/type/typemap.py”第60行:AttributeError:类型对象'User'没有属性'name '
我想念什么吗?
问候
PD:我正在使用Django 2.0.4
Traceback
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x107c49e18>
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/django/utils/autoreload.py", line 225, in wrapper
fn(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 120, in inner_run
self.check(display_num_errors=True)
File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 364, in check
include_deployment_checks=include_deployment_checks,
File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 351, in _run_checks
return checks.run_checks(**kwargs)
File "/usr/local/lib/python3.6/site-packages/django/core/checks/registry.py", line 73, in run_checks
new_errors = check(app_configs=app_configs)
File "/usr/local/lib/python3.6/site-packages/django/core/checks/urls.py", line 13, …Run Code Online (Sandbox Code Playgroud) 我正在学习如何使用 GraphQL 和 python。我找到了graphene项目及其 SQLAlchemy 和 Flask 扩展。我一直在阅读教程和文档,但无法弄清楚class Meta定义模式时的用途。我目前正在关注本教程。我用谷歌搜索了一下,似乎找不到任何东西。
这是教程中的一些代码。我已经对令我困惑的行发表了评论。
从 graphene_sqlalchemy 导入 SQLAlchemyObjectType
从数据库.model_people 导入 ModelPeople
进口石墨烯
# 创建一个通用类来共同描述查询和突变的人员属性
People属性类:
name = graphene.String(description="此人的姓名。")
height = graphene.String(description="人的身高。")
mass = graphene.String(description="人的质量。")
Hair_color = graphene.String(description="人的头发颜色。")
Skin_color = graphene.String(description="人的肤色。")
eye_color = graphene.String(description="人的眼睛颜色。")
birth_year = graphene.String(description="此人的出生年份。")
性别 = graphene.String(description="该人的性别。")
Planet_id = graphene.ID(description="该人来自的星球的全局 ID。")
url = graphene.String(description="星球大战 API 中人物的 URL。")
People 类(SQLAlchemyObjectType,PeopleAttribute):
“”“人员节点。”“”
# ---------- 这个类是用来做什么的?Flask + 石墨烯 + sqlalchemy 生态系统的哪一部分使用了它?
类元:
模特 = 模特人物
接口 = (graphene.relay.Node,)
这个问题已作为 GH 问题发布在https://github.com/graphql-python/graphene-sqlalchemy/issues/134下,但我想我也将其发布在这里以吸引大众。
完整的工作演示可以在https://github.com/somada141/demo-graphql-sqlalchemy-falcon下找到。
考虑以下 SQLAlchemy ORM 类:
class Author(Base, OrmBaseMixin):
__tablename__ = "authors"
author_id = sqlalchemy.Column(
sqlalchemy.types.Integer(),
primary_key=True,
)
name_first = sqlalchemy.Column(
sqlalchemy.types.Unicode(length=80),
nullable=False,
)
name_last = sqlalchemy.Column(
sqlalchemy.types.Unicode(length=80),
nullable=False,
)
Run Code Online (Sandbox Code Playgroud)
简单地包装在SQLAlchemyObjectType这样的中:
class TypeAuthor(SQLAlchemyObjectType):
class Meta:
model = Author
Run Code Online (Sandbox Code Playgroud)
并通过以下方式暴露:
author = graphene.Field(
TypeAuthor,
author_id=graphene.Argument(type=graphene.Int, required=False),
name_first=graphene.Argument(type=graphene.String, required=False),
name_last=graphene.Argument(type=graphene.String, required=False),
)
@staticmethod
def resolve_author(
args,
info,
author_id: Union[int, None] = None,
name_first: Union[str, None] = None,
name_last: Union[str, None] = None,
):
query = …Run Code Online (Sandbox Code Playgroud) 我的 Django 模型如下所示:
class Article(model.Model):
slug = models.SlugField(db_index=True, max_length=255, unique=True)
title = models.CharField(db_index=True, max_length=255)
body = models.TextField()
tags = models.ManyToManyField(
'articles.Tag', related_name='articles'
)
def __str__(self):
return self.title
class Tag(model.Model):
tag = models.CharField(max_length=255)
slug = models.SlugField(db_index=True, unique=True)
def __str__(self):
return self.tag
Run Code Online (Sandbox Code Playgroud)
还有我的 schema.py:
class ArticleType(DjangoObjectType):
class Meta:
model = Article
class Query(ObjectType):
article = graphene.Field(ArticleType, slug=graphene.String())
def resolve_article(self, info, slug):
article = Article.objects.get(slug=slug)
return article
Run Code Online (Sandbox Code Playgroud)
使用以下命令查询此模型:
query {
article(slug: "my_slug") {
id
title
body
slug
tagList: tags {
tag
}
} …Run Code Online (Sandbox Code Playgroud) 如何使用 graphene-django 在 GraphQL 中创建自定义参数?
我目前在 schema.py 中有此配置:
class Post(DjangoObjectType):
class Meta:
model = FeedPost
interfaces = (graphene.relay.Node,)
filter_fields = ['id']
class Query(graphene.ObjectType):
post = graphene.Node.Field(Post)
def resolve_post(self, info, **kwargs):
username = kwargs.get('username')
u = User.objects.get(username=username)
users_sources = FeedSource.objects.filter(user=u)
return FeedPost.objects.filter(feed__feedsource__in=users_sources).annotate(
source_title=F('feed__feedsource__title')
)
schema = graphene.Schema(query=Query)
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何使“用户名”成为“post”的实际 GraphQL 查询中的必需参数。
我使用 Django 和 Graphene 在 Python 中实现了 GraphQL 服务器。我有使用模型形式的突变,大致如下所示:
def mutate(self, info, **kwargs):
form = MyModelForm(kwargs)
if form.is_valid():
form.save()
return MyMutation(instance=form.instance)
raise GraphQLError(json.dumps(form.errors))
Run Code Online (Sandbox Code Playgroud)
也就是说,如果表单验证失败,则将表单错误作为 JSON 字符串发送,以便前端可以整齐地解包错误。这一切都很好。
但是,如果存在其他错误 - 比如说数据库存在问题,当表单尝试保存时会引发异常,或者存在拼写错误,那么石墨烯的默认行为是获取错误消息并在 GraphQL 中传输它错误列表给客户端。这意味着检查响应的任何人都可以看到来自服务器的原始错误消息。这似乎不明智 - 如果该错误消息包含我不想泄漏的信息怎么办?显然,解决方案是创建一个不抛出异常的应用程序,但我无法预见一切。有没有办法告诉石墨烯更加离散,并在错误不是由我显式引发 GraphQLError 引起时提供通用错误消息,而不是仅仅将所有内容发送到客户端?
当前正在发生的事情的一个例子:
{"errors":[{"message":"name 'LogiForm' is not defined","locations":[{"line":2,"column":3}],"path":["login"]}],"data":{"login":null}}
Run Code Online (Sandbox Code Playgroud)
这个特定的示例不是安全问题,很容易在生产之前捕获,但这只是一个示例 - 即使不是安全威胁,我的服务器让客户端可以查看其内部错误消息似乎有点不专业。
我目前正在用装饰器解决这个问题:
def hide_error(mutate):
def new_func(*args, **kwargs):
try:
return mutate(*args, **kwargs)
except Exception as e:
raise e if isinstance(e, GraphQLError) else Exception("Error.")
return new_func
Run Code Online (Sandbox Code Playgroud)
但还有更好的办法吗?您“应该”有办法解决这个问题吗?
python error-handling graphql graphene-python graphene-django
我正在graphene-django用来构建我的 API。我有一个 DjangoObjectType StoreType,它代表模型商店。这个模型有一个 MultiSelectField 命名opening_days,指示商店在一周中的哪几天营业。为了创建新商店,我使用了这个突变:
class Weekdays(graphene.Enum):
MO = "Mo"
TU = "Tu"
WE = "We"
TH = "Th"
FR = "Fr"
SA = "Sa"
SU = "Su"
class CreateStore(graphene.Mutation):
store = graphene.Field(StoreType)
class Arguments:
opening_days = graphene.Argument(graphene.List(Weekdays))
def mutate(self, info, opening_days):
store = Store(opening_days=opening_days)
store.save()
return CreateStore(store=store)
Run Code Online (Sandbox Code Playgroud)
突变完美地工作。但是,当我尝试查询商店时,我得到了"Expected a value of type \"StoreOpeningDays\" but received: Monday, Tuesday",真正有意义的错误,因为此字段将数据保存为单个字符串,值以逗号分隔。问题在于,石墨烯期待的graphene.List(Weekdays)是无法检索到的指定列表。
有想法该怎么解决这个吗?提前致谢!
graphene-python ×10
graphql ×8
python ×7
django ×6
sqlalchemy ×2
flask ×1
postgresql ×1
python-3.x ×1
sql ×1