Reputation: 1358
I'm trying to display a JSON doc in a HTML form, broken into separate input items, allow modifications, then convert it back to a JSON doc.
Firstly I use data = json.load(json_data)
to convert the doc to an object and then pass data
to template, accessing its attributes in the template as so: <input type="hidden" name="countries" value="{{ data.countries }}">
.
Once posted back to the view I'm using doc = json.dumps(request.POST)
to serialize it back to JSON. This works fine for everything bar arrays: "countries": "[u'US']"
, which should instead look like: "countries": ['US']
I could use string operations to clean it up, but is there a better way?
view.py (stripped out the DB code)
def addProducts(request):
if request.POST:
doc = json.dumps(request.POST)
return HttpResponseRedirect('/add_product')
json_data = open('items.json')
data = json.load(json_data)
return render("add_products.html", {
"products": data,
}, context_instance=RequestContext(request))
doc
ends up being a string:
{"doc_type": "Product", "countries": "[u'US']"}
original data in items.json
:
{"doc_type": "Product", "countries": ["US"]}
Upvotes: 2
Views: 1211
Reputation: 56467
Allright. The culprit is this line:
<input type="hidden" name="countries" value="{{ data.countries }}">
In a way you are doing you are actually passing str(data.countries)
to your template (implicitly) which produces these funky errors. You have to serialize it first and then in your view you have to parse it again:
def addProducts(request):
if request.POST:
post = {}
for key in request.POST:
value = request.POST[key]
try:
value = json.loads(value)
except Exception:
pass
post[key] = value
doc = json.dumps(post)
# the other code goes here
return render("add_products.html", {
"products": data,
}, context_instance=RequestContext(request))
Now this looks like an overkill, but it has to be done, since request.POST
is a dictionary of JSON strings (which you have to manually convert to dict/JSON).
Conclusion: having JSON values in forms might not be a good idea in the first place.
Upvotes: 5