What is the best way to send field values for model creation in URL in DRF?

I have and app with books, where I want to have POST request with field's value in URL like

    POST URL:BOOKS/NINETEEN_EIGHTY_FOUR HTTP/1.1 content-type: application/json 
{
    "description": "my favorite book" 
}
    

    RESPONSE
{
    "description": "my favorite book",
    "book_name": "NINETEEN_EIGHTY_FOUR" 
}

What is the best way to do it in DRF? I have my book model with 2 field: description and book_name

And in my views.py I have viewset (connected to router book) which is working with books: for example GET books/ will return full list of books and through @action decorator I get GET/POST books/{book_name} requests

class BookViewSet(ListViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    @action(methods=['get', 'post', ],
            detail=False,
            url_path=r'(?P<book_name>\w+)',)
    def get_or_create_book(self, request, book_name):
        if request.method == 'GET':
            book = get_object_or_404(Book, book_name=book_name)
            etc
        book, create = Book.objects.get_or_create(book_name=book_name)

Are there something better ways?

The approach you are describing is a valid way to handle POST requests with field values in the URL using Django REST framework (DRF).

In the example you provided, you are using the @action decorator to handle GET and POST requests for a specific book. The @action decorator allows you to define additional actions for a viewset that are not covered by the standard CRUD operations. You are also using the url_path parameter to capture the book name from the URL and pass it as an argument to the action method.

In the action method get_or_create_book, you are checking the request method to determine whether to retrieve an existing book or create a new one. If the request method is GET, you are using the get_object_or_404 function to retrieve the book with the specified name, and if the request method is POST, you are using the get_or_create method to retrieve or create the book with the specified name.

This approach is fine for handling simple use cases, but it is important to consider the following:

If you need to handle more complex cases and validations you can use custom views and viewsets. You might want to consider using the create method instead of get_or_create and handle the existing book case with a custom validation. You might want to consider handling the URL params in the routing level, you can use path converters to capture the value from the URL and pass it to the view. Overall, the approach you described is a good way to handle POST requests with field values in the URL, but you should consider your specific use case and adjust it as needed.

Back to Top