Saransh Mohapatra
Saransh Mohapatra

Reputation: 9636

Django-Forms with json fields

I am looking to accept json data in a form field and than validate it using some database operations. The data will mostly consist of an array of integers. So can you please help me as to how can i do so.

I have tried to google this but didn't get any decent answer. Please help.

Upvotes: 22

Views: 43656

Answers (8)

Andre Pereira
Andre Pereira

Reputation: 249

Django 3.1 update

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

class MyForm(forms.Form):
    json_field = forms.JSONField()

Upvotes: 2

jrief
jrief

Reputation: 1695

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.

Upvotes: 3

Googlian
Googlian

Reputation: 6723

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'))

Upvotes: 0

Yuri Kots
Yuri Kots

Reputation: 792

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()
    ...

Upvotes: 1

Danil
Danil

Reputation: 5181

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

Upvotes: 1

Rohan
Rohan

Reputation: 53336

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.

Upvotes: 28

Abbasov Alexander
Abbasov Alexander

Reputation: 1938

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:

Upvotes: 12

almalki
almalki

Reputation: 4775

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

Upvotes: 2

Related Questions