Answer the question
In order to leave comments, you need to log in
How to convert Django model to Json Schema?
Hello!
Strongly do not kick, practical advice is needed.
One project is being developed in the Django + Django Rest Framework backend and in the AngularJS frontend. There was such situation that it is necessary to generate the form of the Django model in Angular. I would like to use Json Schema for this. People give advice on how to convert a Django model to Json Schema? Or which way to dig to convert a Django model to a form?
Thank you very much in advance!!!
Answer the question
In order to leave comments, you need to log in
stackoverflow.com/questions/18561585/django-form-t...
the package is a bit old, but
https://github.com/WiserTogether/django-remote-forms
will do for an example,
but it's better not to reinvent the wheel and www.django-rest- framework.org/topics/html-and-form...
Serialization in Django and json peculiarities
Schema is not very suitable for defining dynamic structures.
I don't know any solutions for automatically obtaining a schema from a model, and I'm not sure that they exist. If you decide to describe with your hands, then I recommend https://jsl.readthedocs.org/en/latest/
sim3x here is the bike needed here :) Since DRF and its TemplateHTMLRenderer render a ready-made form that I cannot use with AngularJS Material. So far I've made a form mixin in Django:
class MDSwitchRenderer(RadioFieldRenderer):
def render(self):
return render_to_string('switch_widget.html', {'field': self})
class MDSwitch(RadioSelect):
renderer = MDSwitchRenderer
class MDSelect(Widget):
allow_multiple_selected = False
def __init__(self, attrs=None, choices=()):
super(MDSelect, self).__init__(attrs)
self.choices = list(choices)
def render(self, name, value, attrs=None, choices=()):
if value is None:
value = ''
final_attrs = self.build_attrs(attrs, name=name)
output = [format_html('<md-select{}>', flatatt(final_attrs))]
options = self.render_options(choices, [value])
if options:
output.append(options)
output.append('</md-select>')
return mark_safe('\n'.join(output))
def render_option(self, selected_choices, option_value, option_label):
if option_value is None:
option_value = ''
option_value = force_text(option_value)
if option_value in selected_choices:
selected_html = mark_safe(' selected')
if not self.allow_multiple_selected:
selected_choices.remove(option_value)
else:
selected_html = ''
return format_html('<md-option data-ng-value="{}"{}>{}</md-option>', option_value, selected_html, force_text(option_label))
def render_options(self, choices, selected_choices):
selected_choices = set(force_text(v) for v in selected_choices)
output = []
for option_value, option_label in chain(self.choices, choices):
if isinstance(option_label, (list, tuple)):
output.append(format_html('<md-optgroup label="{}">', force_text(option_value)))
for option in option_label:
output.append(self.render_option(selected_choices, *option))
output.append('</md-optgroup>')
else:
output.append(self.render_option(selected_choices, option_value, option_label))
return '\n'.join(output)
class MDSelectMultiple(MDSelect):
allow_multiple_selected = True
def render(self, name, value, attrs=None, choices=()):
if value is None:
value = []
final_attrs = self.build_attrs(attrs, name=name)
output = [format_html('<md-select multiple="multiple"{}>', flatatt(final_attrs))]
options = self.render_options(choices, value)
if options:
output.append(options)
output.append('</md-select>')
return mark_safe('\n'.join(output))
def value_from_datadict(self, data, files, name):
if isinstance(data, MultiValueDict):
return data.getlist(name)
return data.get(name)
class MDFormMixin(object):
"""
Angular Material Design form mixin
"""
def __init__(self, *args, **kwargs):
super(MDFormMixin, self).__init__(args, kwargs)
for field_name in self.fields:
field = self.fields.get(field_name)
if field:
if type(field) in (ModelChoiceField, ):
field.empty_label = None
field.widget = MDSelect(choices=field.choices)
elif type(field) in (ModelMultipleChoiceField, ):
field.empty_label = None
field.widget = MDSelectMultiple(choices=field.choices)
if type(field.widget) in (TextInput, Textarea):
field.widget.attrs.update({'md-maxlength': field.max_length, })
#elif type(field.widget) in (TimeInput, ): # FIXME: Remove
# field.widget.input_type = 'time'
# field.widget.attrs.update({'step': 1, })
elif type(field.widget) in (Select, ):
field.widget = MDSelect(choices=field.choices)
if field.required:
field.widget.attrs.update({'required': 'required'})
field.widget.attrs.update({'ng-model': 'vm.object.'+field_name})
<md-radio-group ng-model="vm.object.{{ field.name }}">
{% for choice in field %}
<md-radio-button ng-value="{{ choice.choice_value|lower }}">
{{ choice.choice_label }}
</md-radio-button>
{% endfor %}
</md-radio-group>
{% if form.fieldsets %}
<md-content>
{% for fieldset in form.fieldsets %}
<div{% if fieldset.class %} class="{{ fieldset.classes }}"{% endif %}{% if fieldset.description %} layout="{{ fieldset.description }}{% endif %}">
{% for field in fieldset %}
<md-input-container class="md-block" flex>
<label>{{ field.label }}</label>
{{ field }}
{% if field.help_text %}
<div class="hint">{{ field.help_text }}</div>
{% endif %}
<div ng-messages="vm.objectForm.{{ field.name }}.$error">
<div ng-message="required" ng-show="vm.objectForm.{{ field.name }}.$error['required']">Обязательное поле для заполнения!</div>
<div ng-message="md-maxlength" ng-show="vm.objectForm.{{ field.name }}.$error['md-maxlength']">Длина строки не должна превышать {{ field.field.max_length }} символов.</div>
</div>
</md-input-container>
{% endfor %}
</div>
{% endfor %}
</md-content>
{% endif %}
There is a documentation generator for DRF: rest_framework_swagger. It has similar functionality. You can try to see, especially since you are using DRF.
In the DocumentationGenerator class, the get_models method https://github.com/marcgibbons/django-rest-swagger...
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question