hoo*_*ter 11 django django-forms django-admin
我有一个带有json对象字段的模型.该对象在网站上用于控制一些css变量等.
现在在管理员中,我有一个文本字段,用户可以在其中保存json对象.我想显示一个包含所有属性的表单,在保存时,将生成一个json对象.
基本上,用户看到并存储数据,如下所示:
{
"name":"hookedonwinter",
"user-id":123,
"basics":{
"height":150,
"weight":150
}
}
Run Code Online (Sandbox Code Playgroud)
而且我宁愿让用户看到这个:
Name: <input field>
User Id: <input field>
Height: <input field>
Weight: <input field>
Run Code Online (Sandbox Code Playgroud)
并且数据仍然存储在json中.
任何指导将不胜感激.链接到文档解释这一点,倍加赞赏.
谢谢!
Mar*_*tis 26
基本上你需要做的是将你的JSON渲染到字段中.
您还可以通过覆盖TextField的小部件来跳过步骤1,2.
我尝试编写这个解决方案,这里的解决方案对我有用而没有一些边缘情况.
fields.py
import json
from django.db import models
from django import forms
from django import utils
from django.utils.translation import ugettext_lazy as _
class JSONEditableField(models.Field):
description = _("JSON")
def formfield(self, **kwargs):
defaults = {'form_class': JSONEditableFormField}
defaults.update(kwargs)
return super(JSONEditableField, self).formfield(**defaults)
class JSONEditableWidget(forms.Widget):
def as_field(self, name, key, value):
""" Render key, value as field """
attrs = self.build_attrs(name="%s__%s" % (name, key))
attrs['value'] = utils.encoding.force_unicode(value)
return u'%s: <input%s />' % (key, forms.util.flatatt(attrs))
def to_fields(self, name, json_obj):
"""Get list of rendered fields for json object"""
inputs = []
for key, value in json_obj.items():
if type(value) in (str, unicode, int):
inputs.append(self.as_field(name, key, value))
elif type(value) in (dict,):
inputs.extend(self.to_fields("%s__%s" % (name, key), value))
return inputs
def value_from_datadict(self, data, files, name):
"""
Take values from POST or GET and convert back to JSON..
Basically what this does is it takes all data variables
that starts with fieldname__ and converts
fieldname__key__key = value into json[key][key] = value
TODO: cleaner syntax?
TODO: integer values don't need to be stored as string
"""
json_obj = {}
separator = "__"
for key, value in data.items():
if key.startswith(name+separator):
dict_key = key[len(name+separator):].split(separator)
prev_dict = json_obj
for k in dict_key[:-1]:
if prev_dict.has_key(k):
prev_dict = prev_dict[k]
else:
prev_dict[k] = {}
prev_dict = prev_dict[k]
prev_dict[dict_key[-1:][0]] = value
return json.dumps(prev_dict)
def render(self, name, value, attrs=None):
# TODO: handle empty value (render text field?)
if value is None or value == '':
value = '{}'
json_obj = json.loads(value)
inputs = self.to_fields(name, json_obj)
# render json as well
inputs.append(value)
return utils.safestring.mark_safe(u"<br />".join(inputs))
class JSONEditableFormField(forms.Field):
widget = JSONEditableWidget
Run Code Online (Sandbox Code Playgroud)
models.py
from django.db import models
from .fields import JSONEditableField
class Foo(models.Model):
text = models.TextField()
json = JSONEditableField()
Run Code Online (Sandbox Code Playgroud)
希望这会有所帮助,以下是它的外观:

| 归档时间: |
|
| 查看次数: |
5418 次 |
| 最近记录: |