Джанго эквивалент железнодорожных
В Rails я могу использовать response_to, чтобы определить, как контроллер отвечает в соответствии с форматом запроса.
в route.rb
map.connect '/profile/:action.:format', :controller => "profile_controller"
в profile_controller.rb
def profile
@profile = ...
respond_to do |format|
format.html { }
format.json { }
end
end
В настоящее время в Django мне нужно использовать два URL-адреса и два действия: одно для возврата html и одно для возврата 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)
При таком подходе код для логики становится дублированным. Конечно, я могу определить метод для выполнения логических вычислений, но код пока не многословен.
Есть ли вообще в Джанго, я могу объединить их вместе?
2 ответа
Да, вы можете, например, определить параметр, который определяет формат:
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)
Теперь мы можем определить urls.py
с определенным параметром формата:
urlpatterns = [
url(r'^profile_(?P<format>\w+)', views.profile),
]
Так что теперь Django будет анализировать формат как регулярное выражение \w+
(возможно, вам придется немного это изменить), и это будет передано в качестве параметра формата profile(..)
просмотр вызова.
Обратите внимание, что теперь пользователь может вводить что угодно, например localhost:8000/profile_blabla
, Таким образом, вы можете дополнительно ограничить регулярное выражение.
urlpatterns = [
url(r'^profile_(?P<format>(json|html))', views.profile),
]
Так что теперь только json
а также html
допустимые форматы. Так же, как вы можете определить action
параметр (как ваш первый фрагмент кода, кажется, предлагает).
Из вашего использования классов сериализатора вы, очевидно, используете Django Rest Framework. Поэтому вы должны позволить этой библиотеке выполнять работу здесь, используя рендеры - смотрите документацию.
В вашем случае вы хотите переключаться между JSONRenderer и TemplateHTMLRenderer, и DRF автоматически определит, какой из них использовать, основываясь на заголовке Accept или расширении файла в URL.