Search code examples
djangodjango-rest-frameworklarge-data

Django rest framework: automatically create a url for each field of a model


I have large table of data (~30 Mb) that I converted into into a model in Django. Now I want to have access to that data through a REST API.

I've successfully installed the Django REST framework, but I'm looking for a way to automatically create a URL for each field in my model. My model has about 100 fields, and each field has about 100,000 entries.

If my model is named Sample,

models.py

class Sample(models.Model):
    index = models.IntegerField(primary_key=True)
    year = models.IntegerField(blank=True, null=True)
    name = models.TextField(blank=True, null=True)
    ...97 more fields...

then I can access the whole model using Django REST framework like this:

urls.py
class SampleSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Sample
        fields = ( **100 fields**)

class SampleViewSet(viewsets.ModelViewSet):
    queryset = Sample.objects.all()
    serializer_class = SampleSerializer

router = routers.DefaultRouter()
router.register(r'sample', SampleViewSet)

But of course my browser can't load all of that data in a reasonable amount of time. I could manually make a different class and URL for each field, but there must be a better way... I want to be able to go to my_site.com/sample/year (for example) and have it list all of the years in JSON format, or my_site.com/sample/name and list all the names, etc. Please help me figure out how to do this, thanks!


Solution

  • You might be able to do that using a custom viewset route.

    You have this:

    class ModelViewSet(ModelViewSet):
    
        @list_route()
        def sample_field(self, request):
            desired_field = request.data.get('field', None)
            if not desired_field:
                return response # pseudocode
    
            values = Model.objects.all().values_list(desired_field, flat=True)
            # serialize this for returning the response
            return Response(json.dumps(values))  # this is an example, you might want to do something mode involved
    

    You will be able to get this from the url:

    /api/model/sample_field/?field=foo
    

    This extra method on the viewset will create a new endpoint under the samples endpoint. Since it's a list_route, you can reach it using /sample_field.

    So following your code, it would be:

    mysite.com/sample/sample_field/?field='year'

    for example.

    There are many interesting details in your question, but with this sample I think you might able to achieve what you want.