如何从列表中提取JSON值并以django模型形式呈现它?

如何从列表中提取JSON值并以django模型形式呈现它?,django,django-forms,django-templates,Django,Django Forms,Django Templates,我正在尝试使用下面的模型呈现Django模型表单。问题是其中一个模型字段是JSONField。这是一个长度为1的列表,其中包含一些JSON数据。当我呈现模型表单时,number字段呈现列表,没有任何问题。但是我想从列表中的JSON中提取phone值并呈现它。我已经尝试在模板中提取它,但它没有按预期工作 如何从JSON中提取phone值并将其呈现在表单中?例如,当我使用视图呈现id 1的数据时,我应该在名称字段中看到'Client_1',在数字字段中看到'1234567890' 我使用Django

我正在尝试使用下面的模型呈现Django模型表单。问题是其中一个模型字段是JSONField。这是一个长度为1的列表,其中包含一些JSON数据。当我呈现模型表单时,
number
字段呈现列表,没有任何问题。但是我想从列表中的JSON中提取
phone
值并呈现它。我已经尝试在模板中提取它,但它没有按预期工作

如何从JSON中提取
phone
值并将其呈现在表单中?例如,当我使用视图呈现id 1的数据时,我应该在名称字段中看到'Client_1',在数字字段中看到'1234567890'

我使用Django 3.1和Django Crispy表单来渲染模型表单

数据如数据库中的客户端表所示:

id  name        number
1   Client_1    [{'type': 'mobile', 'phone': '1234567890'}]
2   Client_2    [{'type': 'mobile', 'phone': '3334445555'}]
3   Client_3    [{'type': 'mobile', 'phone': '9876543210'}]
models.py:

forms.py:

clients.html模板:

{% load crispy_forms_tags %}

<form method="POST">
    <div class="form-row">
        <div class="form-group col-md-6">
            {{ form.name | as_crispy_field }}
        </div>
        <div class="form-group col-md-6">
            {% for item in form.number %}
                {{ item.0.phone | as_crispy_field }}
            {% endfor %}
        </div>
    </div>
</form>

您需要将字段动态添加到表单中,以下是一个工作示例:

类ClientForm(forms.ModelForm):
def uuu init uuuu(self,*args,instance=None,**kwargs):
super(ClientForm,self)。\uuuuu init\uuuu(*args,instance=instance,**kwargs)
例如:
对于索引,枚举中的obj(instance.number):
self.fields[f'phone_{index}']=forms.CharField(initial=obj.get('phone','')
def save(self,commit=True):
对于索引,枚举中的obj(self.instance.number):
obj['phone']=self.cleaned_data.get(f'phone_{index}','')
返回super(ClientForm,self).save(commit=commit)
类元:
模型=客户端
字段=['name']
然后,您的模板应为:


{%load crispy_forms_tags%}
{{form.name | as_crispy_field}
{{form.phone|as|u crispy_field}
NB:如果您总是将手机存储在列表中,则应将默认设置为您的JsonField:

类客户端(models.Model):
name=models.TextField()
编号=models.JSONField(默认值=列表)

我在表单中尝试了上面的init和save方法。但它仍然显示如我的问题所示的列表。我不确定我是否做错了什么。我编辑了我的答案,你需要更新你的模板。对不起,我忙于工作。我将很快更新我的答案。我只是好奇。
{{form.phone_1|as_crispy_field}}
对任何ID都有效吗?或者
表单.phone_1
必须是动态的吗?我可以确认您的方法有效。我只需要在模板中做一个小小的更改,就是根据我收到的回溯错误将
{form.phone_1 | as_crispy_field}
更改为
{form.phone_0 | as_crispy_field}
。在做了这个小的更新之后,它工作得非常好。非常感谢您调查此事。老实说,我不知道init方法在做什么…:-)我实际上发现了一个数字字段为空的场景。这导致了一个错误。为了克服这个问题,我稍微修改了ini函数:`if instance.number:for index,obj in enumerate(instance.number):self.fields[f'phone}']=forms.CharField(initial=obj.get('phone',''),else:self.fields[f'phone']=forms.CharField(initial='')`
from .models import Client

class ClientForm(forms.ModelForm):
    class Meta:
        model = Client
        fields = '__all__'
{% load crispy_forms_tags %}

<form method="POST">
    <div class="form-row">
        <div class="form-group col-md-6">
            {{ form.name | as_crispy_field }}
        </div>
        <div class="form-group col-md-6">
            {% for item in form.number %}
                {{ item.0.phone | as_crispy_field }}
            {% endfor %}
        </div>
    </div>
</form>
def clients(request, pk):
    instance = Client.objects.get(pk=pk)

    if request.method == 'POST':
        form = ClientForm(request.POST, instance=instance)
        if form.is_valid():
            form.save()
    else:
        form = ClientForm(instance=instance)

    return render(request, 'clients.html', {'form': form})