我有一个具有以下字段的中间模型:
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))