我环顾了堆栈,但找不到任何答案。 所以我有一个像这样的模型:
class DynamicModel(models.Model):
config = models.JSONField()
def __str__(self):
return self.config
我现在想要做的是将 json 字段键值对显示为独立字段,并且还能够以相同的方式编辑它们,就像它们每个都是一个不同的领域。这是我能想到的最好的创作方式
dynamic fields
因此,如果我有一个像这样的 jsonfield:
{
"age": 23,
"name": "John Doe",
"gender": "Male"
}
我将有一个
Age
字段,我可以在其中编辑值,甚至删除该字段。然后更改将反映到
JSONField
我的方法是这样的:
# form.py
from django import forms
from django.contrib import admin
from .models import DynamicModel
class DynamicModelForm(forms.ModelForm):
class Meta:
model = DynamicModel
fields = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields.pop('config', None)
json_data = self.instance.config or {}
for key, value in json_data.items():
# Add a CharField for each key
self.fields[key] = forms.CharField(initial=value, required=False)
self.fields[key].label = key
self.fields[key].widget.attrs.update({'style': 'display:block;'})
def save(self, *args, **kwargs):
json_data = self.instance.config or {}
cleaned_data = self.cleaned_data
data = self.cleaned_data
for key, value in json_data.items():
config[key] = cleaned_data.get(key, value)
self.instance.config = config
return super().save(*args, **kwargs)
# admin.py
class DynamicModelAdmin(admin.ModelAdmin):
form = DynamicModelForm
list_display = ['config']
admin.site.register(DynamicModel, DynamicModelAdmin)
但这似乎并不能解决问题。我得到的结果是,当尝试添加新实例时:
,如果我尝试编辑旧实例,它是一样的,但唯一的区别是它显示
def __str__(self)
任何帮助。
你几乎就要成功了!问题出在你的
save
方法中。你正在创建名为
config
的局部变量,而不是更新
self.instance.config
。
以下是已更正的
save
方法:
def save(self, *args, **kwargs):
json_data = self.instance.config or {}
for key, value in json_data.items():
# 更新 self.instance.config 而不是创建一个新的局部变量
self.instance.config[key] = self.cleaned_data.get(key, value)
return super().save(*args, **kwargs)
通过此更改,你的动态表单字段现在应该可以正确保存到
JSONField
。
以下是一些额外的技巧:
-
为了更好地控制每个动态字段的呈现,你可以考虑使用
Fieldset
和formfield_overrides
在 Django 管理器中对其进行分组。 - 对于更复杂的情况,你可能希望探索使用 JavaScript 来动态添加和删除表单字段。
祝你好运,编程愉快!
标签:python,django,django-forms,django-admin From: 78002789