具有外键关系的对象在石墨烯中的 GraphQL 突变
GraphQL Mutation in Graphene for Object with Foreign Key Relation
我正在使用 Python、GraphQL (graphene-django) 和 Django 构建一个简单的 CRUD 界面。包含与另一个对象 (Category
) 的外键关系的对象 (Ingredient
) 的 CREATE 变更将不起作用。我想为 GraphQL 提供 CategoryObject 的 id 而不是整个类别实例。然后在后端它应该绘制与类别对象的关系。
在 Django 模型中,成分对象包含外键类别对象的实例(请参见下面的代码)。这里是否需要整个类别对象来绘制关系并使用 Ingredient.objects.select_related('category').all()
?
create mutation 期望 IngredientInput
包括所有属性和外键关系的整数字段。所以 graphQL 突变本身目前可以按照我的意愿工作。
我的问题与 即使不一样也很相似,但这些答案对我没有帮助。
models.py:
class Category(models.Model):
name = models.CharField(max_length=50, unique=True)
notes = models.TextField()
class Meta:
verbose_name = u"Category"
verbose_name_plural = u"Categories"
ordering = ("id",)
def __str__(self):
return self.name
class Ingredient(models.Model):
name = models.CharField(max_length=100)
notes = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
class Meta:
verbose_name = u"Ingredient"
verbose_name_plural = u"Ingredients"
ordering = ("id",)
def __str__(self):
return self.name
schema.py:
class CategoryType(DjangoObjectType):
class Meta:
model = Category
class CategoryInput(graphene.InputObjectType):
name = graphene.String(required=True)
notes = graphene.String()
class IngredientType(DjangoObjectType):
class Meta:
model = Ingredient
class IngredientInput(graphene.InputObjectType):
name = graphene.String(required=True)
notes = graphene.String()
category = graphene.Int()
class CreateIngredient(graphene.Mutation):
class Arguments:
ingredientData = IngredientInput(required=True)
ingredient = graphene.Field(IngredientType)
@staticmethod
def mutate(root, info, ingredientData):
_ingredient = Ingredient.objects.create(**ingredientData)
return CreateIngredient(ingredient=_ingredient)
class Mutation(graphene.ObjectType):
create_category = CreateCategory.Field()
create_ingredient = CreateIngredient.Field()
graphql_query:
mutation createIngredient($ingredientData: IngredientInput!) {
createIngredient(ingredientData: $ingredientData) {
ingredient {
id
name
notes
category{name}
}
graphql 变量:
{
"ingredientData": {
"name": "milk",
"notes": "from cow",
"category": 8 # here I ant to insert the id of an existing category object
}
}
执行查询后的错误消息:
{
"errors": [
{
"message": "Cannot assign \"8\": \"Ingredient.category\" must be a \"Category\" instance.",
"locations": [
{
"line": 38,
"column": 3
}
],
"path": [
"createIngredient"
]
}
],
"data": {
"createIngredient": null
}
}
我今天遇到了同样的问题。
Cannot assign \"8\": \"Ingredient.category\" must be a \"Category\" instance.
错误是一个 Django 错误,当您尝试直接使用外键整数而不是对象来创建对象时会发生该错误。
如果你想直接使用外键 ID,你必须使用 _id
后缀。
例如,而不是使用:
_ingredient = Ingredient.objects.create(name="milk", notes="from_cow", category=8)
你必须使用其中之一
category_obj = Category.objects.get(id=8)
_ingredient = Ingredient.objects.create(name="milk", notes="from_cow", category=category_obj)
或
_ingredient = Ingredient.objects.create(name="milk", notes="from_cow", category_id=8)
在使用 GraphQL 的情况下,您必须将 InputObjectType
字段设置为 _id。在你的情况下:
class IngredientInput(graphene.InputObjectType):
name = graphene.String(required=True)
notes = graphene.String()
category_id = graphene.Int()
然而,这将使您的字段在架构中显示为 categoryId
。如果您希望保留 category
名称,则必须更改为:
category_id = graphene.Int(name="category")
干杯!
我正在使用 Python、GraphQL (graphene-django) 和 Django 构建一个简单的 CRUD 界面。包含与另一个对象 (Category
) 的外键关系的对象 (Ingredient
) 的 CREATE 变更将不起作用。我想为 GraphQL 提供 CategoryObject 的 id 而不是整个类别实例。然后在后端它应该绘制与类别对象的关系。
在 Django 模型中,成分对象包含外键类别对象的实例(请参见下面的代码)。这里是否需要整个类别对象来绘制关系并使用 Ingredient.objects.select_related('category').all()
?
create mutation 期望 IngredientInput
包括所有属性和外键关系的整数字段。所以 graphQL 突变本身目前可以按照我的意愿工作。
我的问题与
models.py:
class Category(models.Model):
name = models.CharField(max_length=50, unique=True)
notes = models.TextField()
class Meta:
verbose_name = u"Category"
verbose_name_plural = u"Categories"
ordering = ("id",)
def __str__(self):
return self.name
class Ingredient(models.Model):
name = models.CharField(max_length=100)
notes = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
class Meta:
verbose_name = u"Ingredient"
verbose_name_plural = u"Ingredients"
ordering = ("id",)
def __str__(self):
return self.name
schema.py:
class CategoryType(DjangoObjectType):
class Meta:
model = Category
class CategoryInput(graphene.InputObjectType):
name = graphene.String(required=True)
notes = graphene.String()
class IngredientType(DjangoObjectType):
class Meta:
model = Ingredient
class IngredientInput(graphene.InputObjectType):
name = graphene.String(required=True)
notes = graphene.String()
category = graphene.Int()
class CreateIngredient(graphene.Mutation):
class Arguments:
ingredientData = IngredientInput(required=True)
ingredient = graphene.Field(IngredientType)
@staticmethod
def mutate(root, info, ingredientData):
_ingredient = Ingredient.objects.create(**ingredientData)
return CreateIngredient(ingredient=_ingredient)
class Mutation(graphene.ObjectType):
create_category = CreateCategory.Field()
create_ingredient = CreateIngredient.Field()
graphql_query:
mutation createIngredient($ingredientData: IngredientInput!) {
createIngredient(ingredientData: $ingredientData) {
ingredient {
id
name
notes
category{name}
}
graphql 变量:
{
"ingredientData": {
"name": "milk",
"notes": "from cow",
"category": 8 # here I ant to insert the id of an existing category object
}
}
执行查询后的错误消息:
{
"errors": [
{
"message": "Cannot assign \"8\": \"Ingredient.category\" must be a \"Category\" instance.",
"locations": [
{
"line": 38,
"column": 3
}
],
"path": [
"createIngredient"
]
}
],
"data": {
"createIngredient": null
}
}
我今天遇到了同样的问题。
Cannot assign \"8\": \"Ingredient.category\" must be a \"Category\" instance.
错误是一个 Django 错误,当您尝试直接使用外键整数而不是对象来创建对象时会发生该错误。
如果你想直接使用外键 ID,你必须使用 _id
后缀。
例如,而不是使用:
_ingredient = Ingredient.objects.create(name="milk", notes="from_cow", category=8)
你必须使用其中之一
category_obj = Category.objects.get(id=8)
_ingredient = Ingredient.objects.create(name="milk", notes="from_cow", category=category_obj)
或
_ingredient = Ingredient.objects.create(name="milk", notes="from_cow", category_id=8)
在使用 GraphQL 的情况下,您必须将 InputObjectType
字段设置为
class IngredientInput(graphene.InputObjectType):
name = graphene.String(required=True)
notes = graphene.String()
category_id = graphene.Int()
然而,这将使您的字段在架构中显示为 categoryId
。如果您希望保留 category
名称,则必须更改为:
category_id = graphene.Int(name="category")
干杯!