Search code examples
pythondjangodjango-modelsdjango-viewsdjango-queryset

Try to Return dataset as a table with request of postman


I wanna Request with postman and get a table of all books as return but I can't find a way to do this. Thanks a lot

This is my model of books:

class Book(models.Model):
    name = models.CharField(max_length=100)
    username = models.ForeignKey(User, on_delete=models.CASCADE)
    publication_date = models.DateField()
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
    description = models.TextField()

    def __str__(self):
        return self.name

And This is my View:

class AddBookAPIView(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'book.html'

    @method_decorator(login_required(login_url='login/'))
    def post(self, request):
        book_serializer = BookSerializer(data=request.data)
        if book_serializer.is_valid():
            book_serializer.save()
            return redirect('home')

        return Response({'message': book_serializer.errors})

    @method_decorator(login_required(login_url='login/'))
    def get(self, request):
        book = Book()
        serializer = BookSerializer(book)
        return Response({'serializer': serializer, 'book': book})

And this is my Template(I try make another url for showing all books and I think template is worng too):

{% load rest_framework %}
<title> Books </title>

{% block title %}<h3> View Books </h3>{% endblock %}

{% block content %}
<form class="form-inline" method="post" novalidate>
    {% csrf_token %}
    {% render_form serializer %}
</form>
{% endblock %}

Solution

  • At first, you can simply apply @method_decorator just above the class itself using name="dispatch'.

    Secondly, try to use many=True in BookSerializer and also use Book.objects.all() to retrieve all instances of Book model, like the following:

    from django.utils.decorators import method_decorator
    from django.contrib.auth.decorators import login_required
    
    @method_decorator(login_required(login_url='login/'), name='dispatch')
    class AddBookAPIView(APIView):
        renderer_classes = [TemplateHTMLRenderer]
        template_name = 'book.html'
    
        def post(self, request):
            book_serializer = BookSerializer(data=request.data)
            if book_serializer.is_valid():
                book_serializer.save()
                return redirect('home')
    
            return Response({'message': book_serializer.errors})
    
        def get(self, request):
            book = Book.objects.all()
            serializer = BookSerializer(book, many=True)
            return Response({'serializer': serializer, 'books': serializer.data})
    

    Try to modify the template so that it would show the list of all books, like the following:

    {% load rest_framework %}
    <title>Books</title>
    
    {% block title %}
        <h3>View Books</h3>
    {% endblock %}
    
    {% block content %}
        <table class="table">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Publication Date</th>
                    <th>Publisher</th>
                    <th>Description</th>
                </tr>
            </thead>
            <tbody>
                {% for book in books %}
                    <tr>
                        <td>{{ book.name }}</td>
                        <td>{{ book.publication_date }}</td>
                        <td>{{ book.publisher }}</td>
                        <td>{{ book.description }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    {% endblock %}