Reputation: 24119
I am receiving the following error:
{
"errors": [
{
"message": "Unknown argument \"project_id\" on field" +
\"get_project_detail_summary\" of type \"Query\".",
"locations": [
{
"line": 2,
"column": 30
}
]
}
]
}
With the following query:
query GetProjectDetailSummary($project_id: Int) {
get_project_detail_summary(project_id: $project_id) {
comments {
... on ManagerCommentNode {
id
text
created
}
... on VendorCommentNode {
id
text
created
}
... on TenantCommentNode {
id
text
created
}
}
}
}
With the following backend code, How can I get to the breakpoint?, or how do I send back custom data given a number?:
class CommentsUnion(graphene.types.union.Union):
class Meta:
name = 'CommentsUnion'
types = (ManagerCommentNode, VendorCommentNode, TenantCommentNode, )
class ProjectSummaryInput(graphene.InputObjectType):
project_id = graphene.Int()
class ProjectSummaryNode(graphene.ObjectType):
Input = ProjectSummaryInput
project_id = graphene.Int()
comments = graphene.List(CommentsUnion)
@classmethod
def resolve_comments(self, *args, **kwargs):
import pdb;pdb.set_trace()
return ProjectSummary.select_related('comments').objects.filter(comments__created__lt=dt)
class Query(graphene.ObjectType):
get_project_detail_summary = Field(ProjectSummaryNode)
Upvotes: 1
Views: 3753
Reputation: 24119
In regards to the error.
Be sure to add a kwarg ( e.g. project_id
in this example, it is the reason for the "unknown argument on field" error ) to the graphene.Field
for get_project_detail_summary
.
Like so:
class Query(graphene.ObjectType):
get_project_detail_summary = Field(ProjectSummaryNode, # see below for example
project_id=graphene.Int() # kwarg here
)
def resolve_get_project_detail_summary(self, info, **kwargs):
return ProjectSummary.objects.get(id=kwargs.get('project_id'))
In regards to returning any data.
This is a way ( returning a graphene.String
), but it untypes the response by putting everything inside a String:
from django.core.serializers.json import DjangoJSONEncoder
class ProjectSummaryRecentUpdatesNode(graphene.ObjectType):
Input = ProjectSummaryInput
recent_updates = graphene.String()
def resolve_recent_updates(self, resolve, **kwargs):
instance = Project.objects.get(id=resolve.variable_values.get("project_id"))
things = instance.things.all()
# these are all from different models, and the list is a bit longer than this.
querysets = (
("scheduled", get_scheduled(things, resolve, **kwargs)),
("completed", get_completed(things, resolve, **kwargs)),
("invoices", get_invoices(things, resolve, **kwargs)),
("expenditures", get_expenditures(things, resolve, **kwargs)),
("comments", get_comments(things, resolve, **kwargs)),
("files", get_files(things, resolve, **kwargs)),
)
recent_updates = []
for update_type, qs in querysets:
for item in qs:
item.update(
{
"recent_update_type": update_type
}
)
recent_updates.append(item)
return json.dumps(recent_updates, cls=DjangoJSONEncoder)
And on the frontend, with an import { Query } from "react-apollo";
element we can JSON.parse
the field ... which has "any" (json serialized) data inside of it:
<Query
query={GET_PROJECT_DETAIL_SUMMARY_RECENT_UPDATES}
fetchPolicy="network-only"
variables={{ project_id: this.props.projectId }}
>
{({ loading, error, data }: QueryResult) => {
if (
data &&
data.get_project_detail_summary_recent_updates &&
data.get_project_detail_summary_recent_updates.recent_updates
) {
console.log(JSON.parse(data.get_project_detail_summary_recent_updates.recent_updates))
}
}}
</Query>
Side note:
If there isn't a large list of data types create a Union
like object which has all of the fields needed from different models, or an actual Union
, which seems like the correct way, as then types are not lost:
class ProjectSummaryNode(graphene.ObjectType):
# from FileNode graphene.ObjectType class
file__id = graphene.Int()
file__brief_description = graphene.String()
file_count = graphene.Int()
last_file_created = graphene.String()
last_file = graphene.String()
# from UploaderNode graphene.ObjectType class
uploader__first_name = graphene.String()
uploader__last_name = graphene.String()
# from CommentNode graphene.ObjectType class
comment = graphene.String()
class Meta:
name = "ProjectSummaryNode"
# example of Union, the above fields would be commented out, as they are part of
# the different graphene.ObjectType classes, and this line below would be uncommented
# types = ( FileNode, UploaderNode, CommentNode, )
Still open to suggestions on a better way to do this.
Upvotes: 1