Django 相当于 rail respond_to
Django equivalent of rail respond_to
在Rails中,我可以使用respond_to来定义控制器如何根据请求格式进行响应。
在routes.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 和两个操作:一个到 return html,一个到 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)
使用这种方法,逻辑代码变得重复。当然我可以定义一个方法来进行逻辑计算,但是代码很冗长。
Django 中有没有,我可以将它们组合在一起?
是的,您可以定义一个参数,指定格式:
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
参数的方式相同(就像您的第一个代码片段似乎暗示的那样)。
从您对序列化程序的使用 类 来看,您显然正在使用 Django Rest Framework。因此,您应该让该库通过使用渲染器来完成此处的工作 - 请参阅 the documentation.
在您的情况下,您希望在 JSONRenderer 和 TemplateHTMLRenderer 之间切换,DRF 将根据接受 header 或 URL 中的文件扩展名自动检测使用哪一个。
在Rails中,我可以使用respond_to来定义控制器如何根据请求格式进行响应。
在routes.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 和两个操作:一个到 return html,一个到 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)
使用这种方法,逻辑代码变得重复。当然我可以定义一个方法来进行逻辑计算,但是代码很冗长。
Django 中有没有,我可以将它们组合在一起?
是的,您可以定义一个参数,指定格式:
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
参数的方式相同(就像您的第一个代码片段似乎暗示的那样)。
从您对序列化程序的使用 类 来看,您显然正在使用 Django Rest Framework。因此,您应该让该库通过使用渲染器来完成此处的工作 - 请参阅 the documentation.
在您的情况下,您希望在 JSONRenderer 和 TemplateHTMLRenderer 之间切换,DRF 将根据接受 header 或 URL 中的文件扩展名自动检测使用哪一个。