0

Is there a way of creating a generic view to be used by several different models? I have many models in my project and do not want to have to create a view and serializer for each of them.

Assume this is a simple solution but I have spent hours googling with no results.

Within the Django REST framework API guide Generic views Examples the following code snippet is shown:

url(r'^/users/', ListCreateAPIView.as_view(model=User), name='user-list')

Which suggests this is possible but the example does not seem to be complete (or my understanding is not complete).

This is my attempt:

url.py

url(r'^foomodel/', views.GenericViewSet.as_view(model = Foomodel) ),

views.py

class GenericViewSet(generics.ListAPIView):
  model = User # this is over ridden by the url 
  queryset = model.objects.all()
  serializer_class = BaseSerializer
  ordering_fields = '__all__'

serializers.py

class BaseSerializer(serializers.ModelSerializer):
    class Meta:
        model = None

And of cause this fails as the serializer does not like model = None or any variation that I can think of.

Any suggestions as to how this should be addressed?

2 Answers 2

1

A solution would be overriding the get_serializer_class method of the ViewSet.

The model field in the view will be fine as you override it in the url, as you said, what I would do is build the serializer class on the fly.

class GenericViewSet(generics.ListAPIView):
    queryset = model.objects.all()

    def get_serializer_class(self):
        class BaseSerializer(serializer.ModelSerializer):
            class Meta:
                model = self.model
        return BaseSerializer

Hope this helps!

Sign up to request clarification or add additional context in comments.

3 Comments

You post was very helpful, but there were more issues once that one was addressed. Thank you for the help!
Can i add an extra field to this serializer? I want to add a type field in serializer
return BaseSerializer.update({'type':'data'}) doesnt work
1

To recap the intention is to create a reusable view that can be used for many models without having to repeat a heap of code. This leaves very little code in Django to create a backed API for many Django models. I am using this for ember.js

urls.py

from myapp import models as mymodels
url(r'^cs/(?P<strmodel>[A-Za-z]+)/(?P<id>[0-9]+)/', views.GenericViewSet.as_view({'get': 'retrieve', 'post':'update', 'delete':'destroy' }, application = mymodels ) ),
url(r'^cs/(?P<strmodel>[A-Za-z]+)/', views.GenericViewSet.as_view({'get': 'list','post': 'create' }, application = mymodels ) ),

Worth noting that I have several apps and there is a different set of URL's to access them. The model being accessed is passed as strmodel

views.py

class GenericViewSet(viewsets.ModelViewSet):

    def __init__(self, application):
        self.application = application

    def initialize_request(self, request, *args, **kwargs):
        self.model = getattr(self.application, self.kwargs['strmodel'] )
        request = super(viewsets.ModelViewSet, self).initialize_request(request, *args, **kwargs)   
        return request

    strmodel = None
    application = None
    model = User
    lookup_field = 'id'

    def get_queryset(self):     
        return self.model.objects.all()

    def get_serializer_class(self):
        class BaseSerializer(serializers.ModelSerializer):      
            class Meta:
                model = self.model
        return BaseSerializer

Hope this helps :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.