ruby-on-railsjsondjangoequivalentrespond-to

Django equivalent of rail respond_to


In Rails, I can use respond_to to define how the controller respond to according to the request format.

in routes.rb

 map.connect '/profile/:action.:format', :controller => "profile_controller" 

in profile_controller.rb

def profile
      @profile = ...
      respond_to do |format|
        format.html {  }
        format.json {  }

      end
end

Currently, in Django, I have to use two urls and two actions: one to return html and one to return json.

url.py:

urlpatterns = [
    url(r'^profile_html', views.profile_html),
    url(r'^profile_json', views.profile_json),
]

view.py

def profile_html (request):

   #some logic calculations

   return render(request, 'profile.html', {'data': profile})

def profile_json(request):

  #some logic calculations

  serializer = ProfileSerializer(profile)

  return Response(serializer.data)

With this approach, the code for the logic becomes duplicate. Of course I can define a method to do the logic calculations but the code is till verbose.

Is there anyway in Django, I can combine them together?


Solution

  • Yes, you can for example define a parameter, that specifies the format:

    def profile(request, format='html'):
        #some logic calculations
    
        if format == 'html':
            return render(request, 'profile.html', {'data': profile})
        elif format == 'json':
            serializer = ProfileSerializer(profile)
            return Response(serializer.data)

    Now we can define the urls.py with a specific format parameter:

    urlpatterns = [
        url(r'^profile_(?P<format>\w+)', views.profile),
    ]
    

    So now Django will parse the format as a regex \w+ (you might have to change that a bit), and this will be passed as the format parameter to the profile(..) view call.

    Note that now, a user can type anything, for example localhost:8000/profile_blabla. You can thus further restrict the regex.

    urlpatterns = [
        url(r'^profile_(?P<format>(json|html))', views.profile),
    ]
    

    So now only json and html are valid formats. The same way you can define an action parameter (like your first code fragment seems to suggest).