如何使用Django的ORM(1.11)从LEFT JOIN'ed表/模型中选择字段

问题描述 投票:0回答:1

上下文:使用Django Rest Framework,我创建了一个ModelViewSet。


有了这些型号:

class Claim(models.Model):
    permalink = models.SlugField(max_length=255, blank=True, unique=True)
    author = models.ForeignKey(get_user_model(), db_index=True, on_delete=models.SET_NULL, null=True, blank=True)
    deleted = models.BooleanField(db_index=True, default=False)
    collaborators = models.ManyToManyField(get_user_model(), through='ClaimCollaborator', through_fields=('claim', 'user'), related_name='claims')
    # ...other fields

class ClaimCollaborator(models.Model):
    claim = models.ForeignKey(Claim, db_index=True, on_delete=models.CASCADE)
    user = models.ForeignKey(get_user_model(), db_index=True, on_delete=models.CASCADE)
    access_project_only = models.BooleanField(default=True)

我正在尝试查询Claim到LEFT JOIN ClaimCollaborator并带回access_project_only字段。 ClaimCollaborator实际上是处理声明和用户(声明的合作者)之间的ManyToMany关系的中间模型。

到目前为止,我有以下观点(为简洁而减少):

class ClaimViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated, )
    serializer_class = serializers.ClaimSerializer
    lookup_field = 'permalink'

    def get_queryset(self):
        return models.Claim.objects.filter(Q(author=self.request.user) | Q(claimcollaborator__user=self.request.user))

串行:

class ClaimSerializer(serializers.HyperlinkedModelSerializer):
    author = serializers.PrimaryKeyRelatedField(allow_null=True, queryset=get_user_model().objects.all())

    class Meta:
        model = Claim
        fields = ('url', 'permalink', 'author', 'deleted')
        lookup_field = 'permalink'
        extra_kwargs = {
            'url': {'lookup_field': 'permalink'},
        }

清单产生这个SQL:

SELECT "api_claim"."permalink", "api_claim"."author_id", "api_claim"."deleted" 
LEFT OUTER JOIN "api_claimcollaborator" ON ("api_claim"."id" = "api_claimcollaborator"."claim_id") 
WHERE ("api_claim"."author_id" = 39 OR "api_claimcollaborator"."user_id" = 39)

所以我在“api_claimcollaborator”(ClaimCollaborator)上获得LEFT JOIN就好了,但没有一个字段。我在查询中尝试了.only(<claim fields>, 'claimcollaborator__access_project_only').selected_related('claimcollaborator'),但这只会产生错误(如果有帮助,我可以更具体地说明我的尝试 - 请告诉我)。

我猜这不是那么简单,因为有问题的表在ORM中被用作ManyToMany?任何帮助将不胜感激。

python sql django orm django-rest-framework
1个回答
1
投票

您可以在序列化程序上使用SlugRelatedField来指示由特定属性标识的相关模型上的字段。

class ClaimSerializer(serializers.HyperlinkedModelSerializer):
    author = serializers.PrimaryKeyRelatedField(allow_null=True, queryset=get_user_model().objects.all())
    claimcollaborator_set = serializers.SlugRelatedField(slug_field='access_project_only', read_only=True, many=True)
    class Meta:
        model = Claim
        fields = ('url', 'permalink', 'claimcollaborator_set', 'author', 'deleted')
© www.soinside.com 2019 - 2024. All rights reserved.