Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass more than one variables to modelViewSet in django rest framework?

I am using http://www.django-rest-framework.org/

I have the scenario where I want to pass two or more variables based on that I need to fetch data from database. In the following code only pk is there which I want to replace with two other fields in database.

Also please suggest how can I write my urlconfig the same.

Views.py

class ExampleViewSet(viewsets.ReadOnlyModelViewSet):
    model = myTable
    def list(self, request):
        queryset = myTable.objects.all()
        serializer = mySerializer(queryset, many=True)
        return Response(serializer.data)
    def retrieve(self, request, pk=None):
        queryset = myTable.objects.all()
        s = get_object_or_404(queryset, pk=pk)
        serializer = mySerializer(s)
        return Response(serializer.data)

Serializer.py

class Serializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = myTable
        fields = ('attr1', 'attr2', 'attr3')
like image 967
theLeanDeveloper Avatar asked Jul 09 '14 15:07

theLeanDeveloper


2 Answers

Here is how you would do it with the recent Django REST Framework.

Assuming your variables are in the resource URLs like so:

GET /parent/:id/child/
GET /parent/:id/child/:id/

Then:

urls.py:

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'parent/(?P<parent_id>.+)/child', views.ExampleViewSet)
urlpatterns = router.urls

views.py:

class ExampleViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = Serializer

    def get_queryset(self):
        parent = self.kwargs['parent']
        return myTable.objects.filter(parent=parent)

Where the 'parent' in the queryset part is your parent object. You may need to adjust it a little, of course, but the idea is encapsulated in the kwargs.

This solution will also save you a little code and you can make it into a full blown ModelViewSet just by subclassing it.

Hope that helps.

More here: DRF Filtering against the URL.

like image 67
Alex Panov Avatar answered Oct 11 '22 12:10

Alex Panov


Here is an example of how you might implement what you want:

class ExampleViewSet(viewsets.ReadOnlyModelViewSet):
# This code saves you from repeating yourself
queryset = myTable.objects.all()
serializer_class = mySerializer

def list(self, request, *args, **kwargs):
    # Get your variables from request
    var1 = request.QUERY_DICT.get('var1_name', None) # for GET requests
    var2 = request.DATA.get('var2_name', None) # for POST requests
    if var1 is not None:
        # Get your data according to the variable var1
        data = self.get_queryset().filter(var1)
        serialized_data = self.get_serializer(data, many=True)
        return Response(serialized_data.data)

    if var2 is not None:
        # Do as you need for var2
        return Response(...)

    # Default behaviour : call parent
    return super(ExampleViewSet, self).list(request, *args, **kwargs)

def retrieve(self, request, *args, **kwargs):
    # Same for retrieve
    # 1. get your variable xyz from the request
    # 2. Get your object based on your variable's value
    s = myTable.objects.get(varX=xyz)
    # 3. Serialize it and send it as a response
    serialized_data = self.get_serializer(s)
    return Response(serialized_data.data)
    # 4. Don't forget to treat the case when your variable is None (call parent method)

As for the urlconf, it depends on how you want to send your variables (get, post or through the url).

Hope this helps.

like image 38
AdelaN Avatar answered Oct 11 '22 11:10

AdelaN