2016-09-19 9 views
3

のdjango restフレームワークのModelViewSetクラスでフォームをレンダリングする残りのフレームワークを使用して私のdjangoモデルのボイラープレートフォームを作成したいと思います。APIView

ドキュメントではAPIView:http://www.django-rest-framework.org/topics/html-and-forms/#rendering-formsを使用しています。

しかし、私はカスタムアクションメソッドの定義を避けるためにModelViewSetを使いたいと思います。

これは可能ですか?あなたは例を共有できますか?

これは私が試みたものです。私のモデル:

class Person(AbstractUser): 
    pass 

マイシリアライザ:

class PersonSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Person 
     fields = ('first_name', 'last_name', 'email', 'groups') 

マイビュー:

class PersonViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows persons to be viewed or edited. 
    """ 
    queryset = Person.objects.all().order_by('-date_joined') 
    serializer_class = PersonSerializer 
    renderer_classes = [TemplateHTMLRenderer] 
    template_name = 'common/rest_create.html' 

そして、ここでは私のURLです:

url(r'person_create_api/$', PersonViewSet.as_view({'get': 'create'}), name='person-create-api'), 

そして、私が取得エラー:

IntegrityError at /school/person_create_api/ 
duplicate key value violates unique constraint "school_person_username_key" 
DETAIL: Key (username)=() already exists. 

私はシリアライザフィールドにusernameフィールドを追加すると、私が手:

HTTP/1.0 400 Bad Request 
Date: Tue, 20 Sep 2016 17:00:22 GMT 
Server: WSGIServer/0.2 CPython/3.5.1+ 
X-Frame-Options: SAMEORIGIN 
Vary: Cookie 
Allow: GET, HEAD, OPTIONS 
Content-Type: text/html; charset=utf-8 

私はジャンゴ1.9と最新のDRF 3.4.6を使用しています。

+0

この機能があれば、私はそのビューの内容を取り上げ、他のビューで使用します。 – mehmet

+0

ModelViewSetの基本クラスは、ModelViewSet> GenericViewSet> GenericAPIView> APIViewです。したがって、APIViewを継承します。 – mehmet

+0

どのバージョンのDRFとDjangoを使用していますか? あなたが作成したmodelviewsetでオーバーレイ/オーバーロードするのではなく、期待どおりの結果を得られないかもしれないとして、あなたのgetを 'as_view'として定義しています。 また、DRFのAPIエンドポイントをルーティングする従来の方法であるルータも使用していません。彼らはドキュメンテーション(http://www.django-rest-framework。org/api-guide/routers /#custom-routers)を参照してください。 「Person」のシリアライザやモデルがどのようなものかわかりません。おそらくそれを含めることができますか? – tredzko

答えて

2

まず最初にまず、DRFはあなたのためのURLを(これはURLの設定ミス防止)を作成してみましょう:

from rest_framework.routers import DefaultRouter 
router = DefaultRouter() 
router.register(r'snippets', PersonViewSet) 

urlpatterns = [ 
    ... 
    url(r'^', include(router.urls)), 
] 

ここのURLが生成されます。

^persons/$ [name='person-list'] 
^persons\.(?P<format>[a-z0-9]+)/?$ [name='person-list'] 
^persons/blank_form/$ [name='person-blank-form'] 
^persons/blank_form\.(?P<format>[a-z0-9]+)/?$ [name='person-blank-form'] 
^persons/(?P<pk>[^/.]+)/$ [name='person-detail'] 
^persons/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='person-detail'] 

モデルは、上記と同じです

class PersonViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows persons to be viewed or edited. 
    """ 
    queryset = Person.objects.all().order_by('-date_joined') 
    serializer_class = PersonSerializer 
    template_name = 'common/rest_create.html' 

    @list_route(renderer_classes=[renderers.TemplateHTMLRenderer]) 
    def blank_form(self, request, *args, **kwargs): 
     serializer = PersonSerializer() 
     return Response({'serializer': serializer}) 

注意:TemplateHtmlRendererはメソッドレベルinstで設定されています他のメソッドやビューに対して他の適切なレンダラーを使用できるようにするために、クラス内でグローバルに使用されます。 DRFサイトのチュートリアルを控えて、serializer = PersonSerializer()これはアンバウンドフォームの生成に使用されます。あなたはいつものようにModelViewSet作業から期待

{% load rest_framework %} 

<html><body>  
<h1>New Person</h1> 

<form action="{% url 'school:person-create' %}" method="POST"> 
    {% csrf_token %} 
    {% render_form serializer %} 
    <input type="submit" value="Save"> 
</form> 

</body></html> 

他のビュー:ここ

とテンプレートです。

+0

この方法では、クラスにメソッドを追加してテンプレートを作成します。私はそれがすぐに使える機能を使ってどうやってやり遂げられるのか、まだ不思議です。 – mehmet

関連する問題