当我使用 Graphene 在 Django GraphQL API 中获取对象时,如何限制 ForeignKey 字段的项目数?
Posted
技术标签:
【中文标题】当我使用 Graphene 在 Django GraphQL API 中获取对象时,如何限制 ForeignKey 字段的项目数?【英文标题】:How to limit the number of items of a ForeignKey field when I'm fetching an object in Django GraphQL API using Graphene? 【发布时间】:2021-09-08 02:47:33 【问题描述】:我有一个简单的聊天应用程序,它带有一个用 Django 编写的带有 Graphene 插件的 GraphQL API。以及以 Apollo 作为 GraphQL 客户端的 Angular UI。我有一个类似于聊天室的聊天模型和一个 chatMessage 模型,它更多的是通过 foreignKey 字段与聊天模型相关联的个人消息,因此每条聊天消息都与某个聊天项目相关联。
以下是Django中的模型规范:-
class Chat(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
admins = models.ManyToManyField(User, related_name="adminInChats", through="ChatAdmin", through_fields=(
'chat', 'admin'), blank=True)
members = models.ManyToManyField(User, related_name="privateChats",
through="ChatMember", through_fields=('chat', 'member'), blank=True)
active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class ChatAdmin(models.Model):
chat = models.ForeignKey(Chat, on_delete=models.CASCADE)
admin = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.chat
class ChatMember(models.Model):
chat = models.ForeignKey(Chat, on_delete=models.CASCADE)
member = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.chat
class ChatMessage(models.Model):
chat = models.ForeignKey(Chat, on_delete=models.PROTECT)
message = models.CharField(max_length=1000)
author = models.ForeignKey(
User, related_name="chatAuthor", on_delete=models.DO_NOTHING)
seenBy = models.ForeignKey(
User, related_name="chatSeenBy", on_delete=models.PROTECT, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.chat
我正在使用 GraphQL 来获取单个聊天项目。以下是它的后端代码:-
class Query(ObjectType):
chat = graphene.Field(ChatType, id=graphene.ID())
@login_required
def resolve_chat(root, info, id, **kwargs):
chat_instance = Chat.objects.get(pk=id, active=True)
if chat_instance is not None:
return chat_instance
else:
return None
我在 Angular 上使用我的 Apollo 客户端调用它:-
GET_CHAT: gql`
query chat($id: ID!)
chat(id: $id)
id
name
admins
id
firstName
lastName
members
id
firstName
lastName
chatmessageSet
message
author
id
firstName
avatar
createdAt
seenBy
firstName
createdAt
`,
因此,当我从客户端进行此查询时,我希望它仅发送该聊天消息集中的前 30 条消息。现在它把所有东西都发给我,这对交通不利。我基本上想给消息分页。
我知道如何为分页做所有其他事情,但我对 Django 中的后端编码不够熟悉,不知道如何指定 resolve_chat
方法,以便它只向我发送属于该聊天的前 30 条聊天消息,在被请求时按 id 降序排序。
resolve_chat
方法怎么写?
【问题讨论】:
【参考方案1】:这是使用中继的好选择。首先,如果您还没有定义ChatMessageType
,则需要将其接口设置为relay.Node
:
class ChatMessageType(DjangoObjectType):
class Meta:
model = ChatMessage
fields = ("message", "author", "seenBy")
interfaces = (graphene.relay.Node,)
然后在您的ChatType
上,像这样定义DjangoFilterConnectionField
:
class ChatType(DjangoObjectType):
...
chat_messages = DjangoFilterConnectionField("ChatMessageType")
然后你可以像这样查询它来限制结果
chat(id: $id)
...
chatMessages(first: 30)
message,
author,
seenBy
...
【讨论】:
以上是关于当我使用 Graphene 在 Django GraphQL API 中获取对象时,如何限制 ForeignKey 字段的项目数?的主要内容,如果未能解决你的问题,请参考以下文章
graphene-django 将 models.BigInteger() 转换为 graphene.Integer()
如何使用 Graphene-Django Relay 中的外键关系更新模型?