Django RESTフレームワークを初めて使用しています。私がやろうとしているのは、ブラウズ可能なAPIでViewSetが自動的にレンダリングされる方法と同様に、HTMLでGeneric APIView(RetrieveUpdateDestroyAPIView)をレンダリングすることです。Django RESTフレームワーク:HTMLレンダリング汎用APIView
公式documentation後、私は私のて、myApp/views.pyで持っている:
class AnnounceViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows announces to be viewed or edited.
"""
queryset = Announce.objects.all()
serializer_class = AnnounceSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
def perform_create(self, serializer): # without this, the POST request of the announce doesnt work
serializer.save(owner=self.request.user)
class AnnounceList(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'myApp/announces_list.html'
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def get(self, request):
queryset = Announce.objects.all()
return Response({'announces': queryset})
class AnnounceDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Announce.objects.all()
serializer_class = AnnounceSerializer
renderer_classes = [TemplateHTMLRenderer]
template_name = 'myApp/announce_detail.html'
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,)
私urls.pyで:
from django.conf.urls import url, include
from rest_framework import routers
from myApp import views
from django.contrib import admin
router = routers.DefaultRouter()
router.register(r'api/users', views.UserViewSet)
router.register(r'api/groups', views.GroupViewSet)
router.register(r'api/announces', views.AnnounceViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('myApp.urls')),
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^accounts/', include('allauth.urls')),
url(r'^announces/$', views.AnnounceList.as_view(), name='announces-list'),
url(r'^announces/(?P<pk>[0-9]+)/$', views.AnnounceDetail.as_view(), name='announce-detail'),
私はブラウズ可能APIを行くとき、 link/api/announces/3 /を介して、認証されたユーザーに応じて適切なアクセス許可を使ってannounceオブジェクトを正しく見ることができます。私はよく理解していれば
{% load rest_framework %}
{% block content %}
<form action="{% url 'announce-detail' pk=announce.pk %}" method="POST">
{% csrf_token %}
{% render_form serializer %}
<input type="submit" value="Save">
</form>
{% endblock content %}
、:ここで
NoReverseMatch at /announces/3/
Reverse for 'announce-detail' with keyword arguments '{'pk': ''}' not found. 3 pattern(s) tried: ['announces/(?P<pk>[0-9]+)/$', 'api/announces/(?P<pk>[^/.]+)\\.(?P<format>[a-z0-9]+)/?$', 'api/announces/(?P<pk>[^/.]+)/$']
は私のannounce_detail.htmlテンプレートです:
しかし、私は/に行き、私はこのエラーを持って、/ 3 /を発表しますDjangoのRESTビュー(ViewSetまたはViewAPI)はJSON形式でデータを取得/配置するためのもので、Djangoの通常ビューはHTMLの通常のレンダリング用です。しかし、Django REST Viewは通常のDjango HTMLレンダリングにも使用できます。公開されたAPIエンドポイントを持つことで、他のアプリケーション(同じWebアプリケーションやその他のWebアプリケーション/モバイルアプリなど)でデータを取得して使用することができます。私が間違っているなら、私を訂正してください。
なぜ私はエラーが発生したのか分かりません... ありがとうございました!
UPDATE 通常APIViewを作成した後、私は彼/彼女がいないときに、ユーザは、[保存]ボタンをクリックしようとすると、ステータス403は、禁止(フォームがレンダリングされますし、管理、および権限は尊敬されますしかし、それでもフィールドは「変更可能」として表示されます。つまり、領域内にテキストを入力できますが、変更を行うオーナーでない場合は[保存]ボタンでデータを保存しません。
myApp/views.py
class AnnounceDetail(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'myApp/announce_detail.html'
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
def get(self, request, pk):
announce = get_object_or_404(Announce, pk=pk)
self.check_object_permissions(self.request, announce) # required for IsOwnerOrReadOnly to work fine see https://stackoverflow.com/questions/25554415/django-rest-framework-ignoring-my-isownerorreadonly-permissions
serializer_context = {
'request': Request(request),
}
serializer = AnnounceSerializer(announce, context=serializer_context)
return Response({'serializer': serializer, 'announce': announce})
def post(self, request, pk):
announce = get_object_or_404(Announce, pk=pk)
self.check_object_permissions(self.request, announce) # required for IsOwnerOrReadOnly to work fine see https://stackoverflow.com/questions/25554415/django-rest-framework-ignoring-my-isownerorreadonly-permissions
serializer_context = {
'request': Request(request),
}
serializer = AnnounceSerializer(announce, context=serializer_context, data=request.data)
if not serializer.is_valid():
return Response({'serializer': serializer, 'announce': announce})
serializer.save()
return HttpResponseRedirect(reverse('announces-list')) # redirect to URL that is associated with the name announces-list
は、あなたの答えをありがとう! しかし、これはフォームをレンダリングしますが、ボタン 'Save'がクリックされると、 '405 Method Not Allowed'が表示されます。さらに、アナウンスではない場合でも、すべてのユーザーは(POSTが機能しなくても)「変更可能な」フォームを見ることができます。私が望むのは、Browsable APIとまったく同じバージョンです(つまり、Announceの所有者だけがフィールドを変更できます)が、HTMLテンプレートでレンダリングされます。 – filipyoo
答えを更新しました。テンプレート(announce_detail.html)を追加しました。もう一度確認できますか? – origamic
答えをありがとう! しかし、まだ動作しません。保存ボタンをクリックしても実際には何も行われません。入力領域を変更前の値にリフレッシュするだけで、変更は保存されません。 私の質問が更新されましたので、ご確認ください。 – filipyoo