обновить jsonfields в наборах форм модели django с помощью mongdb

Я пытаюсь создать редактируемую таблицу начальной загрузки, в которой каждая ячейка представляет значение json. Я определил модель Django с этим JSONField (не 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>

Мы видим, что форма была создана путем добавления идентификаторов и определенных атрибутов на основе полей модели, тогда как ничего из этого не произошло, когда я отображал значения JSONField.

Должен ли я пытаться создать эти поля вручную при создании формы в шаблоне? Или какой подход у меня должен быть здесь?


person Amine Hosni    schedule 26.08.2019    source источник


Ответы (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>
person Amine Hosni    schedule 27.08.2019