2016-09-19 23 views
3

我想使用其餘框架爲我的django模型創建樣板表單。使用Django Rest框架呈現一個表單使用API​​View的ModelViewSet類insead

文檔使用API​​View顯示它: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(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 

我使用Django 1.9和最新的DRF 3.4.6。

+0

一旦這個工作,我會採取該視圖的內容,並在其他視圖中使用它。 – mehmet

+0

ModelViewSet的基類如下:ModelViewSet> GenericViewSet> GenericAPIView> APIView。所以它確實繼承了APIView。 – mehmet

+0

你使用的是什麼版本的DRF和Django? 您正在將您的get定義爲'as_view',而不是在您創建的modelviewset上覆蓋/重載它,這可能無法達到您期望的效果。 您還沒有使用路由器,這是用於爲DRF路由API端點的傳統方式。他們甚至展示瞭如何在文檔中創建一個自定義的(http://www.django-rest-framework。組織/ API-引導/路由器/#定製路由器)。 我也不知道你的序列化器或模型爲'人'看起來像。你可以包括嗎? – tredzko

回答

2

第一件事,第一,讓DRF創建URL對你(這可防止錯誤配置的URL):

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

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

這裏是網址生成:

^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()這用於生成未綁定的表單。

這裏是模板:

{% 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> 

其他意見,你從ModelViewSet照常工作期望。

+0

所以這種方法涉及到在類中添加一個方法並編寫一個模板。我仍然好奇如何使用開箱即用的功能來完成。 – mehmet

相關問題