2016-10-11 54 views
5

我有一個在Django後端驗證器,choicefields等模型形式。我想通過它來反應和顯示它。首先是甚至可能的?我想用驗證器完成它,但html仍然很棒。原因是:ReactJS和Django的形式

  1. 避免在正面和背面的雙常數聲明。例如,選擇選項:「男性」,「女性」,「???」需要在後端進行驗證和前端進行顯示和驗證。
  2. 再次在表單前端構造整個html,儘管它也可以很容易地由django創建。主要擔心的是選擇具有許多不同自定義值的選項。

有一個名爲drf-braces具有FormSerializer但它似乎有問題包,我不斷地得到一個500錯誤「是不是JSON序列化的錯誤」,像:

name_or_event = CharFormSerializerField(error_messages={u'required': 
<django.utils.functional.__proxy__ object>}, help_text='', initial=None, 
label='Name', required=True, validators=[]) is not JSON serializable 

這是如見於DRF-括號的DRF-括號基於串行形式系列化例如:

from drf_braces.serializers.form_serializer import FormSerializer 

from myapp.forms import SignupDataForm 

class MySerializer(FormSerializer): 
    class Meta(object): 
     form = SignupDataForm 

並且基於rest-auth RegisterView的API視圖:

from myapp.serializers import MySerializer 

class TestView(RegisterView): 

    permission_classes = (AllowAny,) 
    allowed_methods = ('GET',) 
    serializer_class = MySerializer 

    def get(self, *args, **kwargs): 
     serializer = self.serializer_class() 
     return Response({'serializer': serializer}, status=status.HTTP_200_OK) 

如果我在瀏覽器中打開分配給TestView的url,我可以看到表單域。但是當從反應中加載ajax時,我得到了一個500,上面是「不是JSON序列化錯誤」。該調用是從React.component構造函數(如下圖)製作的。我不說出來會正確顯示領域,到目前爲止,主要是我試圖打印的響應到控制檯,看到拋出什麼樣的錯誤,但它不到風度走到這一步:

loadUserDetail() { 
    this.serverRequest = $.get("myUrl", function (result) { 
     console.log(result); 
     this.setState({ 
     username: result.name_or_event, 
     email: result.email 
     }); 
    }.bind(this)); 
} 

任何其他的想法這個怎麼做?我的方法完全錯誤,對吧? :-)

回答

6

在我看來,混合django生成的表單和React將會變得一團糟。 更簡潔的方法是讓React處理前端,並使用Django來公開JSON API。 沒有辦法渲染表單服務器端,然後讓React從那裏「拾取」,除非您也在服務器上使用Nodejs和React(React支持服務器端渲染)。

您的Python代碼存在的問題是,DRF串行器應該讀取發送到服務器的輸入並將您希望作爲響應發送的數據序列化。 ModelSerializer知道如何對jango模型進行json編碼,在您試圖對代碼進行JSON編碼的情況下編碼一個序列化程序對象,這不起作用,因爲沒有辦法將該對象轉換爲json。

我明白你不想複製你的表單定義和選項,但你可以很容易地告訴React你需要在表單中使用的選項/選項。通常情況下,您可以通過在模板中呈現腳本標記來實現這一點,您將任何初始數據作爲JSON傳遞,並從Js端讀取。

class TestView(RegisterView): 

    permission_classes = (AllowAny,) 
    allowed_methods = ('GET',) 


    def get(self, *args, **kwargs): 
     initial_data = {'gender_options': [...]} # anything you need to render the form, must be json-serialisable. 
     return Response({'initial_data': json.dumps(initial_data)}, status=status.HTTP_200_OK) 

然後在Django模板渲染(之前您實際上加載JS應用程序文件):

<script>var INITIAL_DATA = {{ initial_data|escapejs }};</script> 

要小心escapejs,這可能是一個安全問題,如果你不是很確定initial_data只包含可信數據。

然後在這一點上,您的INITIAL_DATA全球可用於您的js代碼,因此您可以根據您的React組件。

您仍然可以使用Django表單定義來執行服務器端驗證。

0

感謝法比奧,我現在看到我的方法如何工作:-)不知道我是否接受這個建議,但似乎很可能。

注:我有服務器端渲染。

注2:完整的新手反應&串行& Django的休息框架

我最初試圖實現是我的這部分溶液反應JSX文件:

import React from 'react'; 
import {Router, Route, Link} from 'react-router'; 

class GenderField extends React.Component { 
    render() { 
     return (
       <div className="form-group"> 
        <label htmlFor="gender">Gender</label> 
        <input type="text" className="form-control" id="gender" 
          placeholder="Gender" ref="gender"/> 
       </div> 
       ) 
      } 
} 

export default GenderField; 

一切封閉在渲染可以從django後端生成,實際上是。爲什麼再寫下來?難道真的沒有辦法使用ajax並從後面獲取它嗎?我想這可能是反對反應的哲學,一次又一次地從服務器獲取靜態內容...

但是,更廣泛..我正在尋找一種方法來做到這一點從開發人員的角度來看,只有部署之前:服務器生成html並用它填充jsx文件並轉到生產或類似的東西。就像一個Django的應用程序...這是不可能的,仍然是一個錯誤的方式來思考這個?

+1

查看此Q/A瞭解更多相同主題。 https://stackoverflow.com/questions/42297614/django-forms-with-reactjs/42299578#42299578 – pymarco