【问题标题】:update jsonfields in django model formsets with mongdb使用 mongodb 更新 django 模型表单集中的 json 字段
【发布时间】:2023-03-10 01:03:01
【问题描述】:

我正在尝试创建一个可编辑的引导表,其中每个单元格代表一个 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 的值时没有发生任何情况。

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

【问题讨论】:

    标签: django mongodb formset django-jsonfield


    【解决方案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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-28
      • 2011-09-04
      相关资源
      最近更新 更多