我在我的项目中使用了 Django、GraphQL (graphene-django)、VueJS 和 Apollo Client 的组合。在我尝试管理 many2many 关系之前,一切正常。通常,当我对已经在缓存中的对象进行更新突变时,会检测到它并更新显示的数据。问题是,在我的新案例中,我正在更新我的两个对象之间的 many2many 关系并且它没有更新,而它在数据库中正确完成(甚至在缓存中,当我在控制台中打印它时,它是奇怪的)。通常,我试图在组中/从组中添加/删除用户。也许我已经看我的代码太久了,我看不到明显的东西。无论如何这是我的代码:
我的 Django 模型:
class Group(models.Model):
def _get_users_count(self):
return self.user_ids.count()
name = models.CharField(max_length=255)
user_ids = models.ManyToManyField(User, related_name="group_ids", db_table="base_group_user")
users_count = property(fget=_get_users_count, doc="type: Integer")
def __str__(self):
return self.name
class User(AbstractUser):
def _get_full_name(self):
return "%s %s" % (self.first_name, self.last_name.upper())
full_name = property(fget=_get_full_name, doc="type: String")
def __str__(self):
return self.full_name
def _has_group(self, group_name):
return self.group_ids.filter(name=group_name).exists()
我的模式:
class GroupType(DjangoObjectType):
class Meta:
model = Group
fields = ('id', 'name', 'user_ids',)
users_count = graphene.Int()
class UserType(DjangoObjectType):
class Meta:
model = User
fields = (
'id',
'username',
'password',
'first_name',
'last_name',
'is_active',
'group_ids',
)
full_name = graphene.String()
我的突变体:
class AddUserInGroup(graphene.Mutation):
id = graphene.ID()
name = graphene.String()
class Arguments:
group_id = graphene.ID()
user_id = graphene.ID()
class Meta:
output = GroupType
def mutate(self, info, **kwargs):
group = get_object_or_404(Group, id=kwargs['group_id'])
user = get_object_or_404(User, id=kwargs['user_id'])
group.user_ids.add(user)
return group
class RemoveUserFromGroup(graphene.Mutation):
id = graphene.ID()
name = graphene.String()
class Arguments:
group_id = graphene.ID()
user_id = graphene.ID()
class Meta:
output = GroupType
def mutate(self, info, **kwargs):
group = get_object_or_404(Group, id=kwargs['group_id'])
user = get_object_or_404(User, id=kwargs['user_id'])
group.user_ids.remove(user)
return group
我的 js 常量(gql 查询):
const ADD_USER_IN_GROUP_MUTATION = gql`
mutation addUserInGroupMutation ($groupId: ID!, $userId: ID!) {
addUserInGroup(
groupId: $groupId,
userId: $userId
) {
id
name
usersCount
userIds {
id
username
}
}
}
`
const REMOVE_USER_FROM_GROUP_MUTATION = gql`
mutation remoteUserFromGroupMutation ($groupId: ID!, $userId: ID!) {
removeUserFromGroup(
groupId: $groupId,
userId: $userId
) {
id
name
usersCount
userIds {
id
username
}
}
}
`
const GROUPS_QUERY = gql`
query {
groups {
id
name
usersCount
userIds {
id
username
}
}
}
`
我的模板(样本):这些是 2 列。当我删除一个用户时,它应该从左列中删除,它应该出现在不在组中的用户(右列)中,当我添加一个用户时,它应该从右列转到左列。
<b-tab>
<template v-slot:title>
Users
<b-badge class="ml-2">{{ group.usersCount }}</b-badge>
</template>
<b-row>
<b-col>
<b-table :items="group.userIds" :fields="table_fields_users_in">
<template v-slot:cell(actionOut)="row">
<b-button @click="removeUserFromGroup(row.item)" size="sm" variant="danger" title="Remove">
<font-awesome-icon :icon="['fas', 'minus-circle']"/>
</b-button>
</template>
</b-table>
</b-col>
<b-col>
<b-table :items="users" :fields="table_fields_users_out">
<template v-slot:cell(actionIn)="row">
<b-button @click="addUserInGroup(row.item)" size="sm" variant="success" title="Add">
<font-awesome-icon :icon="['fas', 'plus-circle']"/>
</b-button>
</template>
</b-table>
</b-col>
</b-row>
</b-tab>
我的数据:(以便您了解它们的来源)。请注意,我应该将“用户”细化为尚未/不再在组中的用户。
props: {
group: Object,
editing: {
type: Boolean,
default: false
}
},
apollo: { users: USERS_QUERY },
最后是我的方法:
addUserInGroup (user) {
this.$apollo.mutate({
mutation: ADD_USER_IN_GROUP_MUTATION,
variables: {
groupId: this.group.id,
userId: user.id
},
update: (cache, { data: { addUserInGroup } }) => {
console.log('cache : ') // currently used for debugging, will be removed
console.log(cache) // currently used for debugging, will be removed
console.log('query answer: ') // currently used for debugging, will be removed
console.log(addUserInGroup) // currently used for debugging, will be removed
}
})
console.log('Added ' + user.username + ' to ' + this.group.name + ' group.')
},
removeUserFromGroup (user) {
this.$apollo.mutate({
mutation: REMOVE_USER_FROM_GROUP_MUTATION,
variables: {
groupId: this.group.id,
userId: user.id
},
update: (cache, { data: { removeUserFromGroup } }) => {
console.log('cache : ') // currently used for debugging, will be removed
console.log(cache) // currently used for debugging, will be removed
console.log('query answer : ') // currently used for debugging, will be removed
console.log(removeUserFromGroup) // currently used for debugging, will be removed
}
})
console.log('Removed ' + user.username + ' from ' + this.group.name + ' group.')
}
如果你们需要更多代码(有些部分我会忘记),请随时告诉我,我会提供。
我正在做的一个示例(这样你会注意到我的演示数据实际上是通过砸我的键盘制作的):