I have a modelform in django backend with validators, choicefields and etc. I would like to pass it to react and display it. First of all is that even possible? I would like to get it completly with validators, but just html is still great. The reason for that is:
There is a package called drf-braces that has a FormSerializer but it does seem to have a problem, I constantly get a 500 error "is not JSON serializable error", like in:
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
This is the drf-braces based serializer as seen in drf-braces form serialization example:
from drf_braces.serializers.form_serializer import FormSerializer
from myapp.forms import SignupDataForm
class MySerializer(FormSerializer):
class Meta(object):
form = SignupDataForm
and the API view based on rest-auth RegisterView:
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)
If I open the url assigned to TestView in browser I can see the form fields. But when loading with ajax from react I get a 500 with "is not JSON serializable error" above. The call is made from React.component constructor like bellow. I don't say it would display the field correctly, so far mostly I tried to print the response in to console and see what error that throws, but it dosn't get that far:
loadUserDetail() {
this.serverRequest = $.get("myUrl", function (result) {
console.log(result);
this.setState({
username: result.name_or_event,
email: result.email
});
}.bind(this));
}
Any other ideas how to do this? I am completely wrong with my approach, right? :-)
The React. js framework is an open-source JavaScript framework and library developed by Facebook. It's used for building interactive user interfaces and web applications quickly and efficiently with significantly less code than you would with vanilla JavaScript.
React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”.
To get an overview of what React is, you can write React code directly in HTML. But in order to use React in production, you need npm and Node.js installed.
If you're looking for a versatile language that is easy to learn, then Python is a great choice. However, if you're looking for a language specifically designed for developing user interfaces, then ReactJs is the better option.
In my opinion mixing the django-generated forms and React is going to be a mess. A much cleaner approach would be to let React handle the frontend side and use Django to just expose a JSON api. There is no way to render the form server side and then let React "pick up" from there, unless you use Nodejs and React on the server too (React supports server side rendering).
The problem you have with your Python code is that DRF serialisers are supposed to read input sent to the server and to serialise data you want to send as a response. The ModelSerializer knows how to json-encode Django models, in your code you're trying to JSON-encode a serializer object, which doesn't work as there's no magic way to turn that object into json.
I understand you don't want to duplicate your form definitions and options, but you can just easily tell React the options/choices you need to use in the form. Normally you can achieve that by rendering a script tag in the template where you pass any initial data as JSON and you read that from the Js side.
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)
Then in the Django template you render (before you actually loads the js app files):
<script>var INITIAL_DATA = {{ initial_data|escapejs }};</script>
Be careful about escapejs
, that can be a security issue if you are not absolutely sure initial_data contains only trusted data.
Then at this point you have INITIAL_DATA that is globally available to your js code, so you can base your React components on that.
You can still use the Django form definitions to perform server-side validation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With