【发布时间】:2021-10-13 01:10:53
【问题描述】:
我目前正在使用带有 Graphene 的 Python 和 Django 来为我的 Graphql 后端建模。我的问题类似于 Graphene 的 repo https://github.com/graphql-python/graphene/issues/431 上的这个问题。我也在使用 graphene_django_optimizer 库来提高性能。
但是,我很难理解如何在当前情况下将@syrusakbary 提出的解决方案应用于我的问题。任何帮助将不胜感激
这是我要执行的查询
getUser(userId: $userId)
{
id
username
trainings{
id
name
sessions{
id
createdAt
completedAt
category
}
}
}
}
培训是正确的,只有属于该特定用户 ID 的培训。然而,每次培训的所有课程都是为所有用户带来的。我希望会话也特定于该单个用户。在我的 types.py 上是相关类型
class SessionType(DjangoObjectType):
class Meta:
model = Session
fields = "__all__"
convert_choices_to_enum = False
@classmethod
def get_queryset(cls, queryset, info, **kwargs):
if info.context.user.is_anonymous:
return queryset.order_by('-id')
return queryset
class TrainingType(gql_optimizer.OptimizedDjangoObjectType):
class Meta:
model = Training
fields = "__all__"
convert_choices_to_enum = False
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
fields = "__all__"
这是我的相关模型:
class Training(models.Model):
name = models.CharField(max_length=200, help_text='Training\'s name')
details = models.TextField(default="", help_text='Descriptive details about the training')
course = models.ForeignKey("Course", related_name="trainings", on_delete=models.CASCADE)
user = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="trainings")
metric_cards = models.TextField(default="", help_text="An object describing the metrics to be used. (Optional)")
def __str__(self):
return str(self.id) + ' - ' + self.name
class Session(models.Model):
name = models.CharField(max_length=200, help_text='Session\'s name')
category = models.CharField(max_length=240, choices=SESSION_CATEGORIES, default="practice",
help_text='Session type. Can be of \'assessment\''
'or \'practice\'')
total_steps = models.IntegerField(default=1, help_text='Amount of steps for this session')
created_at = models.DateTimeField(editable=False, default=timezone.now, help_text='Time the session was created'
'(Optional - default=now)')
completed_at = models.DateTimeField(editable=False, null=True, blank=True, help_text='Time the session was finished'
'(Optional - default=null)')
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="training_sessions", on_delete=models.DO_NOTHING)
training = models.ForeignKey("Training", related_name="sessions", on_delete=models.CASCADE)
def __str__(self):
return self.name
根据每种类型,我的解析器位于单独的文件中,例如 类 SessionQuery(graphene.ObjectType) 包含与会话相关的所有解析器。像这样的:
class SessionQuery(graphene.ObjectType):
debug = graphene.Field(DjangoDebug, name='_debug')
# Session Queries
session = graphene.Field(SessionType, id=graphene.Int(), user_id=graphene.Int(required=True))
last_created_session = graphene.Field(SessionType)
all_sessions = graphene.List(SessionType,
first=graphene.Int(),
skip=graphene.Int(),)
latest_activities = graphene.List(LatestActivity, limit=graphene.Int())
activity_in_range = graphene.List(UserRangeActivity, start_date=graphene.Date(), end_date=graphene.Date())
unique_users_activity_in_range = graphene.Int(start_date=graphene.Date(), end_date=graphene.Date())
def resolve_last_created_session(root, info):
return Session.objects.latest('id')
def resolve_all_sessions(root, info,first=None,skip=None):
if skip:
return gql_optimizer.query(Session.objects.all().order_by('-id')[skip:], info)
elif first:
return gql_optimizer.query(Session.objects.all().order_by('-id')[:first], info)
else:
return gql_optimizer.query(Session.objects.all().order_by('-id'), info)
(只是代码的一部分,因为太多了,其余的无关紧要)
现在,据我所知,要实现我想要的,我需要在 TrainingQuery 类下有一个类似 resolve_sessions 的东西,在那里我可以有一个参数 user_id,我只是从嵌套链中传递下来的。但我没有该领域的解析器。 Sessions 是一个 Session 的列表,它是 Training 模型中的外键,当我在查询中有这样的东西时会自动带上这个列表:
training
{
id
name
sessions {
id
name
}
}
我想我想要实现的查询是这样的:
query getUser($userId: Int!) {
getUser(userId: $userId)
{
id
username
trainings{
id
name
sessions(userId: Int){
id
createdAt
completedAt
category
}
}
}
}
但是我可以在哪个地方/解析器实现这样的事情?它在我的 SessionType 的 get_queryset 方法中吗?如果有,怎么做?
我在正确的道路上吗?
【问题讨论】:
标签: python django graphql graphene-python graphene-django