0

Using Django REST framework I created an url which maps to a page with a JSON file containing all the objects in my database.

I want to do the same but instead of showing all the objects I want only the objects that match a specific category (category is an attribute in my model).

I have urls that show a JSON files with a single object in it (using the pk attribute) but when I try to do the same thing with category instead of pk I get a MultipleObjectsReturned error.

I'm just sperimenting with the REST framework, I tried using different views and class based views solving nothing.

Any hint or suggestion is really appreciated thanks.

# models.py

class Hardware(models.Model):
    name = models.CharField(max_length=25)
    category = models.CharField(choices=CATEGORY_CHOICES, max_length=2)

    def get_api_url(self):
        return api_reverse("category-api-postings:post-rud", kwargs={'category': self.category})

#views.py

class HardwareListView(generics.ListCreateAPIView):
    pass
    lookup_field = 'pk'
    serializer_class = HardwareSerializer

    def get_queryset(self):
        query = self.request.GET.get("q")
        qs = Hardware.objects.all()
        if query is not None:
            qs = qs.filter(Q(title__icontains=query) | Q(content__icontains=query)).distinct()
        return qs


class HardwareRudView(generics.RetrieveUpdateDestroyAPIView):
    pass
    lookup_field = 'category'
    serializer_class = HardwareSerializer

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

#urls.py

app_name = 'category-api-postings'

urlpatterns = [
    path('', exercise_view),
    path('list-api/', HardwareListView.as_view(), name='all'),
    path('list-api/<str:category>/', HardwareRudView.as_view(), name='post-rud')

#serializer.py

class HardwareSerializer(serializers.ModelSerializer):

    url = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Hardware
        fields = [
            'url',
            'pk',
            'name',
            'category'
        ]
    read_only_fields = ['user']

    def get_url(self, obj):
        return obj.get_api_url()
2
  • Can you please show traceback of the exception? Commented Sep 29, 2019 at 19:35
  • @EugenePrikazchikov Sorry for late response: dpaste.com/2GX88FA Commented Sep 30, 2019 at 12:16

1 Answer 1

1

As I understand, you want url /list-api/HD/ to return all Hardware objects from given category. For that HardwareRudView must inherit ListAPIView, not RetrieveUpdateDestroyAPIView. For example, like this:

class HardwareRudView(generics.ListAPIView):
    serializer_class = HardwareSerializer

    def get_queryset(self):
        category = self.kwargs['category']
        return Hardware.objects.filter(category=category)

See related docs: https://www.django-rest-framework.org/api-guide/filtering/#filtering-against-the-url

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

1 Comment

I swear I red this one second after I've done the same thing, it works perfectly, thanks for your time

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.