Django + Django Rest框架:在中间模型上得到正确的相关对象



我有一个具有以下字段的中间模型:

class UserSkill(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
skill = models.ForeignKey(Skill, on_delete=models.CASCADE, related_name='user_skills')
disabled = models.BooleanField(default=False)
如您所见,它有两个外键,一个指向授权用户,一个指向另一个名为skill的表.

我试图获得分配给特定用户的所有技能,因此我执行以下操作get_querysetin my ViewSet:

class AssignedSkillViewSet(viewsets.ModelViewSet):
queryset = Skill.objects.all()
serializer_class = AssignedSkillSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
user = self.request.user
return Skill.objects.filter(user_skills__user=user, user_skills_user__disabled=False))

现在,我还需要在API中包含中间模型信息,我可以通过users_skills访问它在DRF的序列化器中的相关名称,如下所示:

class AssignedSkillSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Skill
fields = [
'id',
'url',
'title',
'description',
'user_skills',
]

但是当我试图获取该信息时它返回ALLUser_skills与分配的技能相关,无论是否分配给其他用户。我只需要该用户和该技能的相关模型信息。

例如:如果我有一个名为Math的技能,用户名为Maria

related_skills = Skill.objects.filter(user_skills__user=user, user_skills_user__disabled=False)).user_skills.all()

以上代码将返回:

[
<UserSkill: Math+Jenniffer>,
<UserSkill: Math+Gabriel>,
<UserSkill: Math+John>,
<UserSkill: Math+Maria>,
]

我只需要得到项目。该列表没有任何顺序,因此获取列表上的最后一项并非在所有情况下都有效。

我知道我可能错过了什么。我很感激你们能给我的任何帮助或线索。

在这种情况下,您需要使用Prefetch..[Django-doc]对象,使用自定义查询集,使用与主查询集相同的过滤器,如下所示:

from django.db.models import Prefetch

def get_queryset(self):
user = self.request.user
return Skill.objects.filter(
user_skills__user=user, 
user_skills__user__disabled=False,
).prefetch_related(
"user_skills",
queryset=UserSkill.objects.filter(
user=user, 
user__disabled=False,
)
)

我认为当你做过滤器时:

Skill.objects.filter(
user_skills__user=user,   #condition_1
user_skills_user__disabled=False, #condition_2
).user_skills.all()

您已经执行了与UserSkill模型相关的查询。因为过滤是在Skill模型中完成的,而#condition_1 (user_skills__user=user)使用来自UserSkill模型的信息按用户进行过滤。但是,当您在查询结束时执行.user_skills.all()时,您将使用来自UserSkill模型的所有数据覆盖过滤器。

要从过滤器中获得UserSkill实例的列表,您可以尝试:

UserSkill.objects.filter(
user="Maria", 
skill="Math",
)

这可能会有帮助
serializers.py

class SkillSerializer(serializers.ModelSerializer):
class Meta:
model = Skill
fields = ['id', ...]
class UserSkillSerializer(serializers.ModelSerializer):
skill_detail = SkillSerializer(many=True)
class Meta:
model = UserSkill
fields = ['id', 'user', 'skill_detail']

views.py

class AssignedSkillViewSet(viewsets.ModelViewSet):
queryset = UserSkill.objects.all()
serializer_class = UserSkillSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
user = self.request.user
return UserSkill.objects.filter(user=user, disabled=False))

相关内容

  • 没有找到相关文章

最新更新