forest
forest

Reputation: 1464

Django: ModelViewSet router not working for update action

I am using ModelViewSet and Modelserializer for a blog like project.

It could be my difficulty in understanding the implementation; I can't get the update action to work via calling it through router, only the list action is working with the route I have defined.

When I put the url : 127.0.0.1:8000/api/blogs/1, to return the blog with ID 1 to edit, it returns {"Detail": "Not Found."}.

This is my view:

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

I have also overridden the save and update methods in the serializer class, don't know whether it was needed for ModelViewSet in ModelSerializer.

class ArticleSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        article = Article.objects.create(
            article_title = self.validated_data['article_title'],
            article_content = self.validated_data['article_content'],
            ...
        )
        return article

    def update(self, instance, validated_data):
        instance.article_title = validated_data.get('article_title', instance.article_title)
        instance.article_content = validated_data.get('article_content', instance.article_content)
        ...
        instance.save()
        return instance

    class Meta:
        model = Article
        fields = ...

And the urls.py file:

router = DefaultRouter()
router.register(r'blogs', ArticleViewSet, basename='articles-list')
urlpatterns = router.urls

My question is: 1. How do I specify urls for the ModelViewSet actions (in my case the update action)? 2. Will defining only one url suffice all my needs with every ModelViewSet actions? if so how?

What am I doing wrong? I'm new to DRF.

Upvotes: 2

Views: 2377

Answers (2)

forest
forest

Reputation: 1464

Found the issue. I was trying the url localhost/api/blogs/1. It was returning this: "Detail": "Not Found". It was because there were no instance saved with the id 1. All my saved intance had different ids which i didn't notice before. After putting available ids, it returned desired result.

Upvotes: 0

Artur Shyshko
Artur Shyshko

Reputation: 153

Regarding your questions:

1) Upon registering ModelViewSet in api router, it will create all required urls for the following actions. In your case it would be following:

  • list (GET request to /api/blogs/)
  • retrieve (GET request to /api/blogs/{pk}/)
  • create (POST request to /api/blogs/)
  • update (PUT request to /api/blogs/{pk}/) (it will validate all fields of the model)
  • partial update (PATCH request to /api/blogs/{pk}/) (it will run no validation - you can send only fields you've decided to change)
  • delete (DELETE request to /api/blogs/{pk}/)

So, basically router does most of the job for you about registering viewset actions.

2) I don't completely get it, but if my guess is correct - answer is the same as to first question.

About what you are doing wrong - I am not sure, but did you try appending slash at the end of your request (i.e not /api/blogs/1 but /api/blogs/1/)

Upvotes: 2

Related Questions