[Django]-Django-Forms with json fields

28πŸ‘

βœ…

You need to take it as text input using CharField. And in the clean method of this field, you can validate it as per your requirement to check if input is valid.

Something like:

class myForm(forms.Form):
     jsonfield = forms.CharField(max_length=1024)

    def clean_jsonfield(self):
         jdata = self.cleaned_data['jsonfield']
         try:
             json_data = json.loads(jdata) #loads string as json
             #validate json_data
         except:
             raise forms.ValidationError("Invalid data in jsonfield")
         #if json data not valid:
            #raise forms.ValidationError("Invalid data in jsonfield")
         return jdata

You may also find a custom field for JSON data input.

πŸ‘€Rohan

10πŸ‘

You can make forms with fields from JSON data with that decision

Example:

forms.py

# -*- coding: utf-8 -*-
from django import forms
from splitjson.widgets import SplitJSONWidget


class testForm(forms.Form):
    attrs = {'class': 'special', 'size': '40'}
    data = forms.CharField(widget=SplitJSONWidget(attrs=attrs, debug=True))

views.py

# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext
from forms import testForm


def test_dict(request):
    json = {'a': 1,
            'b': 2,
            'c': 3,
            'd': 4}
    form = testForm(request.POST or None, initial={'data': json})
    if form.is_valid():
        # validate and save
        pass

    template = 'test_template.html'
    context = RequestContext(request, {'form': form})
    return render_to_response(template, context)

template.py

<!doctype html>
<html>
    <head></head>
    <body>
        Errors: 
        {% for field, error in form.errors.items %}
            <ul>
            <li>{{ error }}</li>
            </ul>
        {% empty %}
            no errors 
        {% endfor %}
        <hr/>
        List of:
            <form action="" method="post">
                {% csrf_token %}
                {{ form.as_p}}
                <input type="submit" value="Submit" />
            </form>
    </body>
</html>

Result:

3πŸ‘

If your Django model contains a JSON-field named, say scope, which either is a django.contrib.postgres.forms.jsonb.JSONField or a jsonfield.fields.JSONField, then simple rewrite your Django ModelForm as:

from django.form import fields
from entangled.forms import EntangledModelForm

class MyForm(EntangledModelForm):
    field1 = fields.CharField()
    ...
    class Meta:
        entangled_fields = {'scope': ['field1', ...]}

The class EntangledModelForm is a special variant of a Django ModelForm and must be imported from the 3rd-party library django-entangled.

This allows you to edit one or more JSON-fields with all the benefits, such as form validation and data cleaning, as provided by standard Django forms.

πŸ‘€jrief

2πŸ‘

Check django-json-field which implements JSONField and associated form field.

πŸ‘€almalki

1πŸ‘

There’s the most popular github repository with JSONField implementation.
You can install it with:

pip install jsonfield

For example, if you have a model

from jsonfield import JSONField
from django.db import models


class MyModel(models.Model):
    json_field = JSONField(default='', blank=True)

You can simply define a form with JSON validation

from django import forms
from jsonfield.fields import JSONFormField
from myapp import models


class MyModelForm(forms.ModelForm):
    class Meta:
        model = models.MyModel
        fields = '__all__'
        field_classes = {
            'json_field': JSONFormField,
        }

and use this form in your admin model

from django.contrib import admin

from myapp.forms import MyModelForm
from myapp.models import MyModel


@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm
πŸ‘€Danil

1πŸ‘

django.contrib.postgres has a JSONField form field. Here is a link to docs. Field is represented by an HTML <textarea>.

from django import forms
from django.contrib.postgres.forms.jsonb import JSONField

class ExampleForm(forms.Form):
    ...

    metadata = JSONField()
    ...
πŸ‘€Yuri Kots

1πŸ‘

Django 3.1 update

With the introduction of JSONField all you need to do is:

class MyForm(forms.Form):
    json_field = forms.JSONField()
πŸ‘€Andre Pereira

0πŸ‘

In simple:

You do not want to change the default behavior of all your forms just use one function which will transform your request to objects.

form = myForm(jsonForm(request))

if form.is_valid():
   # Continue your stuffs 

You can convert the request body to Python objects and pass to your form instead of passing the request directly.

def jsonForm(req):
    return json.loads(req.body.decode('utf-8'))
πŸ‘€Googlian

Leave a comment