6
votes

I am developing a website where i have to show

1) web pages with html content-type

2) also provide api json end points to develop web or mobile apps.

Presently for html web pages i have used djangos views and forms.

And for api i was using Django rest frameworks views and serializers.

But after going through DRF i have found that DRF can render multiple formats.

HTML & Forms REST framework is suitable for returning both API style responses, and regular HTML pages. Additionally, serializers can used as HTML forms and rendered in templates.

http://www.django-rest-framework.org/topics/html-and-forms/

You can use TemplateHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.

http://www.django-rest-framework.org/api-guide/renderers/#templatehtmlrenderer

Since with one view (one endpoint) i can get both the html and api will that not make my coding efforts less.

I am planning to use only DRF views and searializers instead of DJango forms and views for any type of content.

What will be the setbacks if I only use DRF.

2

2 Answers

7
votes

One cannot use DRF without Django since DRF is not an autonomous framework.
So in order to use DRF, you will base it on a Django app. Therefore the option to use Django views or not is up to you and the problem you want to solve.

Usually, there are no drawbacks on using only the DRF views and serializers, but as I mentioned, that depends on the problem at hand. Some threads listing some reasons on why to use DRF can be found here and here.

Finally, DRF gives you the option to use a "situational" renderer with the option request.accepted_renderer (example straight from the documentation):

In some cases you might want your view to use different serialization styles depending on the accepted media type. If you need to do this you can access request.accepted_renderer to determine the negotiated renderer that will be used for the response.

For example:

@api_view(('GET',))
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def list_users(request):
    """
    A view that can return JSON or HTML representations
    of the users in the system.
    """
    queryset = Users.objects.filter(active=True)

    if request.accepted_renderer.format == 'html':
        # TemplateHTMLRenderer takes a context dict,
        # and additionally requires a 'template_name'.
        # It does not require serialization.
        data = {'users': queryset}
        return Response(data, template_name='list_users.html')

    # JSONRenderer requires serialized data as normal.
    serializer = UserSerializer(instance=queryset)
    data = serializer.data
    return Response(data)    

which covers the second part of your question.

-1
votes

I guess you want to see your API information and have some form where you can create another object. For this you can use APIView from rest-framework

I have a project with something like this:

from rest_framework.views import APIView
from rest_framework.response import Response

class MonitorList(APIView):

    ''' List all Monitors, or create a new Monitor '''

    def get(self, request, format=None):
        monitors = Monitor.objects.all()
        serializer = MonitorSerializer(monitors, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = MonitorSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class MonitorDetail(APIView):

    ''' GET, PUT AND DELETE METHODS FOR Monitor '''
    def get_object(self, pk):
        try:
            return Monitor.objects.get(pk=pk)
        except Monitor.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        monitor = self.get_object(pk=pk)
        serializer = MonitorSerializer(monitor)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        monitor = self.get_object(pk=pk)
        serializer = MonitorSerializer(monitor, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        monitor = self.get_object(pk=pk)
        monitor.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

If you want the option to create or edit some object, you should have post, put or even patch methods. Can read docs for more information about DRF views. Hope I can help you. :)