简体   繁体   中英

How can I get a Django-Rest Framework with a sub-query on child related items working?

I've got a model that looks a bit like this:

Dataset

class Dataset(ClusterableModel):


    group = models.ForeignKey(DataGroup, on_delete=models.CASCADE, related_name='datasets')

    is_public = models.BooleanField(default=False)

    title = models.CharField(max_length=255)
    name = models.CharField(max_length=255, unique=True)

DataGroup

class DataGroup(models.Model):
    name = models.CharField(max_length=255, unique=True)

And I've got something working in DRF that looks like this:

class DataGroupSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='datagroup-detail')
    datasets = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='dataset-detail', lookup_field='name')

    class Meta:
        model = DataGroup
        fields = ['id', 'name', 'url', 'datasets']


class DataGroupViewSet(viewsets.ModelViewSet):
    queryset = DataGroup.objects.all()
    serializer_class = DataGroupSerializer

But, my issue is that the Datasets should be filtered for users.

Now, with the Datasets, they get subset with this:

def get_queryset(self):
    return self.queryset.for_user(self.request.user)

But, my question is how can I do what with the DataGroupSerializer above?

EDIT: I tried something as suggested below, here:

class DatasetInDataGroupField(serializers.HyperlinkedRelatedField):
    def get_queryset(self):
        user = self.context['request'].user
        queryset = Dataset.objects.for_user(user)
        print(list(queryset))
        return queryset


class DataGroupSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='datagroup-detail')
    datasets = DatasetInDataGroupField(many=True, view_name='dataset-detail', lookup_field='name')

    class Meta:
        model = DataGroup
        fields = ['id', 'name', 'url', 'datasets']

And I get only the datasets that have permissions being printed, but all of them appear in the datasets list... So trying something else.

您想要使用HyperlinkedRelatedField而不是PrimaryKeyRelatedField类似于https://medium.com/django-rest-framework/limit-related-data-choices-with-django-rest-framework-c54e96f5815e的内容

This is how I solved it in the end. Works pretty well.

class DatasetInGroupSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='dataset-detail', lookup_field='name')

    class Meta:
        model = Dataset
        lookup_field = 'name'
        fields = [
            'name', 'url']


class DataGroupSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='datagroup-detail')

    datasets = serializers.SerializerMethodField()

    class Meta:
        model = DataGroup
        fields = ['id', 'name', 'url', 'datasets']

    def get_datasets(self, obj):
        queryset = obj.datasets.all()
        if 'request' in self.context:
            queryset = queryset.for_user(self.context['request'].user)
        serializer = DatasetInGroupSerializer(queryset, many=True, context=self.context)
        return serializer.data


class DataGroupViewSet(viewsets.ModelViewSet):
    queryset = DataGroup.objects.all()
    serializer_class = DataGroupSerializer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM