Stevy
Stevy

Reputation: 3387

Django filtering queryset based on input from URL

I am trying to get an API endpoint api/v1/device-groups/?customer=<customer_uuid> which returns the device groups related to the customer_uuid given in the URL but am not sure how to create this.

models.py

class Customer(models.Model):
    customer_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
    customer_name = models.CharField(max_length=128, unique=True)

class DeviceGroup(models.Model):
    group_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
    customer_uuid = models.ForeignKey(Customer, on_delete=models.DO_NOTHING)
    device_group_name = models.CharField(max_length=20)
    color = models.CharField(max_length=8)
    is_default = models.BooleanField(default=False)

serializers.py

class CustomerSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Customer
        fields = ('customer_name', 'customer_uuid')


class DeviceGroupSerializer(serializers.HyperlinkedModelSerializer):
    customer = CustomerSerializer(many=False, read_only=True, source='customer_uuid')

    class Meta:
        model = DeviceGroup
        fields = ('device_group_name', 'group_uuid', 'color', 'is_default', 'customer')

I am not sure what I should do in my views.py and urls.py

urls.py

router = routers.DefaultRouter()

router.register(r'device-groups', views.DeviceGroupViewSet, base_name='device-groups')

urlpatterns = [
    url(r'api/v1/', include(router.urls)),
]

My views.py that returns all device groups related to this customer_uuid upon a GET request to /api/v1/device-groups/?customer_uuid=0bc899e9-4864-4183-8bcd-06937c572143/

class DeviceGroupViewSet(viewsets.ModelViewSet):
    serializer_class = DeviceGroupSerializer

queryset = DeviceGroup.objects.filter(customer_uuid='0bc899e9-4864-4183-8bcd-06937c572143')

I tried to override get_queryset like this, but it results in a KeyError

views.py

class DeviceGroupViewSet(viewsets.ModelViewSet):
    serializer_class = DeviceGroupSerializer

    def get_queryset(self):
        return DeviceGroup.objects.filter(customer_uuid=self.kwargs['customer_uuid'])

What do I need to change to get an API endpoint /api/v1/device-groups/?customer=<customer_uuid>/ that returns filtered device groups?

EDIT

Changing my views.py solved it for me.

class DeviceGroupViewSet(viewsets.ModelViewSet):
    serializer_class = DeviceGroupSerializer

    def get_queryset(self):
        return DeviceGroup.objects.filter(customer_uuid=self.request.GET['customer_uuid'])

Upvotes: 0

Views: 2619

Answers (1)

dirkgroten
dirkgroten

Reputation: 20692

Anything after the ? in a URL is considered to be a list of query parameters: ?customer=<uuid> means you're passing the query parameter customer to your request. They are not part of the actual URL path.

These query parameters are all added to the QueryDict request.GET by Django. In DRF, they can be accessed in request.data as well.

Upvotes: 1

Related Questions