ReactJS 和 django-forms
Posted
技术标签:
【中文标题】ReactJS 和 django-forms【英文标题】:ReactJS & django-forms 【发布时间】:2017-02-19 17:46:06 【问题描述】:我在 django 后端有一个带有验证器、选择字段等的模型表单。我想通过它来做出反应并显示它。首先,这可能吗?我想用验证器完整地得到它,但只是 html 仍然很棒。原因是:
-
避免正面和背面的双重常量声明。例如选择选项:“男”、“女”、“???”需要在后端进行验证,在前端进行显示和验证。
再次在前端为表单构建整个 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-authRegisterView的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,我可以看到表单字段。但是当从 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));
任何其他想法如何做到这一点?我的方法完全错误,对吧? :-)
【问题讨论】:
【参考方案1】:在我看来,将 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 表单定义来执行服务器端验证。
【讨论】:
【参考方案2】:感谢 Fabio,我现在知道我的方法是如何行不通的 :-) 不确定我是否接受了这个建议,但似乎很有可能。
注意:我有服务器端渲染。
注意2:完整的新手反应和序列化器和django-rest-framework
我最初试图实现的是我的 react 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;
render 中包含的所有内容都可以从 django 后端生成,实际上是。为什么又写下来了?真的没有办法使用ajax并从后面获取它吗?我想一遍又一遍地从服务器获取静态内容可能违反反应哲学......
但是,更广泛.. 我正在寻找一种从开发人员的角度来执行此操作的方法,仅在部署之前执行一次:服务器生成 html 并用它填充 jsx 文件并进入生产或类似的东西。就像一个 django 应用程序......这也是不可能的,仍然是错误的思考方式吗?
【讨论】:
查看此 Q/A 以了解有关同一主题的更多信息。 ***.com/questions/42297614/django-forms-with-reactjs/…以上是关于ReactJS 和 django-forms的主要内容,如果未能解决你的问题,请参考以下文章
使用 ReactJS 和 Skeleton Css 滚动表格