Джанго эквивалент железнодорожных - PullRequest
0 голосов
/ 28 июня 2018

В Rails я могу использовать response_to, чтобы определить, как контроллер отвечает в соответствии с форматом запроса.

в маршрутах. 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 ]

0 голосов
/ 28 июня 2018

Используя классы сериализатора, вы, очевидно, используете Django Rest Framework. Поэтому вы должны позволить этой библиотеке выполнять работу здесь, используя рендеры - см. документацию .

В вашем случае вы хотите переключаться между JSONRenderer и TemplateHTMLRenderer, и DRF автоматически определит, какой из них использовать, основываясь на заголовке Accept или расширении файла в URL.

0 голосов
/ 28 июня 2018

Да, вы можете, например, определить параметр, который определяет формат:

def profile(request<b>, format='html'</b>):
    #some logic calculations

    <b>if format == 'html':</b>
        return render(request, 'profile.html', {'data': profile})
    <b>elif format == 'json':</b>
        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 (как, по-видимому, подсказывает ваш первый фрагмент кода).

...