Добавление динамических полей через админку django
Я просмотрел весь стек, но не нашел ответов. Итак, у меня есть такая модель:
class DynamicModel(models.Model):
config = models.JSONField()
def __str__(self):
return self.config
Теперь я хочу отобразить пары ключ-значение json-поля как отдельные поля и иметь возможность редактировать их таким же образом, как если бы каждое из них было отдельным полем. Это был лучший способ, который я смог придумать для создания dynamic fields
. Итак, если у меня есть json-поле следующего вида:
{
"age": 23,
"name": "John Doe",
"gender": "Male"
}
I would have an `Age` field where I can edit the value or even remove the field alotgether. The changes would then reflect to the `JSONField`.
Мой подход таков:
# forms.py
from django import forms
from .models import DynamicModel
class DynamicModelForm(forms.ModelForm):
class Meta:
model = DynamicModel
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Check if 'config' is in the fields
if 'config' in self.fields:
# Extract JSON data from the instance or initialize an empty dictionary
json_data = self.instance.config if self.instance and 'config' in self.instance else {}
# Loop through the JSON data and add individual fields
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;'})
# Remove the original JSON field
self.fields.pop('config', None)
def clean(self):
cleaned_data = super().clean()
json_data = cleaned_data.get('config', {})
# Loop through the JSON data and add individual fields
for key, value in json_data.items():
cleaned_data[key] = value
return cleaned_data
# admin.py
from django.contrib import admin
from .models import DynamicModel
class DynamicModelAdmin(admin.ModelAdmin):
form = DynamicModelForm
list_display = ['config']
admin.site.register(DynamicModel, DynamicModelAdmin)
но это, похоже, не решает проблему. Любая помощь приветствуется.
Идея заключается в том, чтобы работать с эмти ModelForm
, которые затем динамически размещаются:
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)
Таким образом, мы добавляем поля, более или менее похоже на то, как вы сами это определили. Когда мы захотим сохранить элемент, мы перегруппируем поля в словарь и сохраним его в экземпляре.