0

我正在尝试创建一个可编辑的引导表,其中每个单元格代表一个 json 值。我已经用这个JSONField定义了一个 Django 模型(不是 Postgres 的)这是我的模型

class Extracted_Tables(models.Model):
...
content = JSONField(blank=True, null=True)

我的模板

<tbody>
            {% for form in formset.forms %}
                <tr>
                    {% for field in form %}
                        {% if field.is_hidden %}
                        <input type="hidden" >{{ field }}</input>
                        {% else %}
                            {% for k,v in field.value.items %}
                                <td>{{v}}</td>
                            {% endfor %}
                        {% endif %}
                    {% endfor %}
                </tr>
            {% endfor %}
        </tbody>

此模板呈现以下HTML

<tr>
<td>Jamaica</td>
<td>Kingston</td>
<td>North America</td>
<td>11424</td>
<td>2500000</td>
<input type="hidden"><input type="hidden" name="formset_1-0-id" value="353" id="id_formset_1-0-id">
</tr>

为了更好地了解它为什么不起作用:我使用了一个 Django 模型,其中我的单元格是这个模型的属性。在这种情况下,我在编辑模型字段时编辑单元格没有问题 这一次,我的单元格本身不是模型的字段:我拥有的唯一模型字段是 JSONField,我正在尝试编辑那些单元格json 的值。

型号

class Extracted_Variables(models.Model):
    variables = models.CharField(max_length=500)
    values = models.CharField(max_length=500)

模板:_

    <tbody>

        {% for form in formset.forms %}
            <tr>
                {% for field in form %}
                    {% if field.is_hidden %}
                    <input type="hidden" >{{ field }}</input>
                    {% else %}
                    <td>{{ field }}</td>
                    {% endif %}
                {% endfor %}
            </tr>
        {% endfor %}
    </tbody>

渲染的模板

<tr>
<td><input type="text" name="form2-0-variables" value="variable 1" maxlength="500" class="form-control" id="id_form2-0-variables"></td>
<td><input type="text" name="form2-0-values" value="whatever" maxlength="500" class="form-control" id="id_form2-0-values"></td>
<input type="hidden"><input type="hidden" name="form2-0-id" value="1" id="id_form2-0-id">
</tr>

我们看到表单是通过添加 Id 和基于模型字段的特定属性创建的,而当我显示 JSONField 的值时,这些都没有发生。

在模板中创建表单时,我是否应该尝试手动创建这些字段?或者我应该在这里有什么方法?

4

1 回答 1

1

我终于找到了一种使更新成为可能的方法。

这是我的观点

if formset.is_valid():
        answer = request.POST
        #'answer' est la liste des clées récupérées depuis le post. Elles contiennent 4 elements au début dont on a pas besoin
        # et un dernier element "submit" dont on a pas besoin non plus. On retirant tout ces elements, il ne reste que les élements
        # des objets postés qu'on veur récupérer pour faire l'update. Je l'ai appelé 'keys'
        keys = list(answer.keys())[5:-1]
        d = {} # dictionary to hold 'content' for each new Extracted_Variable to update
        list_new_content = []
        list_ids = []
        for idx,k in enumerate(keys): # idx commence de 0
            # print("k: {} v: {}".format(k,v)) retourne ce résultat: (exemple)
            # k: formset_1-0-content__Name v: Argentina babe
            # k: formset_1-0-content__Capital v: Buenos Aires
            # k: formset_1-0-content__Country List Continent v: South America
            # k: formset_1-0-content__Area v: 2777815
            # k: formset_1-0-content__Population v: 32300003
            # k: formset_1-0-id v: 610
            # 1er element : Name, 2ème element: Capital ... et 6ème et dernier element l'id. 
            # len(keys) : c'est le nombre de clées totales récupérées.
            # len(objects.object_list) : c'est le nombre d'objets affichées sur la page. Notes bien que même si on affiche 10 objets
            # par page et que par exemple on n'a que 19 elements, sur la 2ème page, on n'a que 9 élements. Donc len(objects.object_list)
            # nous retourne le nombre exact d'objets sur la page
            # pour un objet Extracted_Variable donnée, son attribut 'content' contient un certain nombre de clées
            # Pour connaitre ce nombre de clées, on divise le nombre de clées présentes sur la page, sur le nombre d'objets figurant
            # sur cette page. Si par exemple 10 elements sont affichées sur la page, on a 60 keys en tout. Cette division nous donnerait
            # donc 6. 6 est constituée de 5 premiers elements qui sont ce qui compose son attribut 'content' et le dernier element
            # est celui de l'id

            v = answer[k]
            indicator = (idx+1) % (len(keys) / len(objects.object_list)) # if idx+1/(60/10)==0 c'est que c'est le 6ème element: id 
                # De même, 1er element (Name) sera distinguée par == 1

            if k.rpartition('__')[0]!= '':
                d[k.rpartition('__')[2]] = v


            if (idx+1) % (len(keys) / len(objects.object_list)) == 0: # 6th element. if idx+1/(60/10)==0 c'est que c'est le 6ème element: 
                # id . De même, 1er element (Name) sera distinguée par == 1

                list_ids.append(v)

                list_new_content.append(d.copy())


        for current_id, new_content in zip(list_ids,list_new_content):
            # print("current_id: {} \t content: {}".format(current_id, new_content))
            obj = Extracted_Tables.objects.get(pk=current_id)
            if obj.content != new_content:
                obj.content = new_content
                obj.save()
        formset = Extracted_TablesFormSet(queryset=page_query,prefix='formset_1')

我将我的模板修改为:

       <tbody>
            {% for form in formset.forms %}
                <tr>
                    {% for field in form %}
                        {% if field.is_hidden %}
                        <input type="hidden" >{{ field }}</input>
                        {% else %}
                            {% for k,v in field.value.items %}
                            <td>
                                <input type="text" name="formset_1-{{ forloop.parentloop.parentloop.counter0 }}-content__{{ k }}" value="{{ v }}" maxlength="500" class="form-control" id="formset_1-{{ forloop.parentloop.parentloop.counter0 }}-content__{{ k }}">
                            </td>

                            {% endfor %}
                        {% endif %}
                    {% endfor %}
                </tr>
            {% endfor %}
       </tbody>
于 2019-08-27T12:02:31.523 回答