json - ReactJS 和 django 表单

标签 json django reactjs django-forms django-rest-framework

我在 django 后端有一个带有验证器、选择字段等的模型表单。我想传递它来 react 并显示它。首先,这可能吗?我想用验证器来完成它,但只有 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

这是基于 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

以及基于rest-auth的API View 注册查看:

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,我可以看到表单字段。但是,当从 React 中使用 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));
}

还有其他想法如何做到这一点吗?我的方法完全错误,对吗? :-)

最佳答案

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

您的 Python 代码存在的问题是,DRF 序列化器应该读取发送到服务器的输入,并序列化您想要作为响应发送的数据。 ModelSerializer 知道如何对 Django 模型进行 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 仅包含可信数据,这可能会导致安全问题。

此时,您的 js 代码可以全局使用 INITIAL_DATA,因此您可以在此基础上构建您的 React 组件。

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

关于json - ReactJS 和 django 表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39972933/

相关文章:

django - 如何从现场添加经理

javascript - React JS onChange 事件没有被触发

javascript - 当我根据其他状态更新状态时,React 给出错误 "Too many re-renders. React limits the number of renders to prevent an infinite loop."

java - 如何为数组或列表(非项目名称)创建java json dto?

jquery - 为什么 JSON.stringify() 不将数据传递给 $.cookie()

vapor 对象的 JSON 数组

php - 如何整合Django站点和php脚本

python - 性能突然从 1024 字节下降到 1025 字节

java - 读取从 PHP 回显的字符串到 java 中?

reactjs - Azure 应用服务上符号链接(symbolic link)上的 yarn EPERM(不允许操作)