ReactJS&django-forms

Ste*_*fan 5 django json django-forms django-rest-framework reactjs

我在django后端有一个带有验证器,选择域等的模型.我想通过它来做出反应并显示它.首先是即便可能吗?我想用验证器来完成它,但只是html仍然很棒.原因是:

  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
Run Code Online (Sandbox Code Playgroud)

这是基于drf-braces的序列化程序,如drf-braces形式的序列化示例所示:

from drf_braces.serializers.form_serializer import FormSerializer

from myapp.forms import SignupDataForm

class MySerializer(FormSerializer):
    class Meta(object):
        form = SignupDataForm
Run Code Online (Sandbox Code Playgroud)

以及基于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)
Run Code Online (Sandbox Code Playgroud)

如果我在浏览器中打开分配给TestView的URL,我可以看到表单字段.但是当从反应中加载ajax时,我得到一个500,其中"不是JSON可序列化错误".调用来自Relow.component构造函数,如bellow.我没有说它会正确显示该字段,到目前为止,我大多试图将响应打印到控制台并查看引发的错误,但它不会那么远:

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

任何其他想法如何做到这一点?我的方法完全错了,对吧?:-)

fab*_*tto 7

在我看来,混合django生成的形式和React将是一团糟.更简洁的方法是让React处理前端并使用Django来暴露JSON api.没有办法渲染表单服务器端,然后让React从那里"拾取",除非你在服务器上也使用Nodejs和React(React支持服务器端渲染).

您的Python代码存在的问题是,DRF序列化程序应该读取发送到服务器的输入并将要作为响应发送的数据序列化.ModelSerializer知道如何json编码Django模型,在你的代码中你试图对序列化器对象进行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)
Run Code Online (Sandbox Code Playgroud)

然后在Django模板中渲染(在实际加载js app文件之前):

<script>var INITIAL_DATA = {{ initial_data|escapejs }};</script>
Run Code Online (Sandbox Code Playgroud)

请注意escapejs,如果您不完全确定initial_data仅包含可信数据,那么这可能是一个安全问题.

那么此时您的INITIAL_DATA可以全局用于您的js代码,因此您可以将React组件作为其基础.

您仍然可以使用Django表单定义来执行服务器端验证.