通过表单集保存编辑的数据

时间:2019-02-03 16:44:13

标签: python django django-forms

我试图通过表单集在模型中编辑多行数据。在呈现的表单中,我使用javascript删除(隐藏并分配DELETE)行,然后使用post保存更改。

我的观点:

def procedure_template_modification_alt(request, cliniclabel, template_id):
    msg = ''
    clinicobj = Clinic.objects.get(label=cliniclabel)
    template_id = int(template_id)
    template= ProcedureTemplate.objects.get(templid = template_id)       
    formset = ProcedureModificationFormset(queryset=SectionHeading.objects.filter(template = template))   

    if request.method == 'POST':
        print(request.POST.get)
        # Create a formset instance with POST data.
        formset = ProcedureModificationFormset(request.POST)
        if formset.is_valid():
            print("Form is valid")
            instances = formset.save(commit=False)
            print(f'instances:{instances}')
            for instance in instances:
                print(f'Instance: {instance}')
                instance.template = template
                instance.save()
            msg = "Changes saved successfully."
            print("Deleted forms:")
            for form in formset.deleted_forms:
                print(form.cleaned_data)
        else:
            print("Form is invalid")
            print(formset.errors)
            msg = "Your changes could not be saved as the data you entered is invalid!"

    template= ProcedureTemplate.objects.get(templid = template_id)
    headings = SectionHeading.objects.filter(template = template)

    return render(request, 'procedures/create_procedure_formset_alt.html',
    {
        'template': template,
        'formset': formset,
        'headings': headings,
        'msg': msg,
        'rnd_num': randomnumber(),
    })

我的模特:

class ProcedureTemplate(models.Model):
    templid = models.AutoField(primary_key=True, unique=True)
    title = models.CharField(max_length=200)
    description = models.CharField(max_length=5000, default='', blank=True)
    clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.description}'        

class SectionHeading(models.Model):
    procid = models.AutoField(primary_key=True, unique=True)
    name = models.CharField(max_length=200)
    default = models.CharField(max_length=1000)
    sortorder = models.IntegerField(default=1000)

    fieldtype_choice = (
        ('heading1', 'Heading1'),
        ('heading2', 'Heading2'),
        )
    fieldtype = models.CharField(
        choices=fieldtype_choice, max_length=100, default='heading1')

    template = models.ForeignKey(ProcedureTemplate, on_delete=models.CASCADE, null=False)

    def __str__(self):
        return f'{self.name} [{self.procid}]'

我的表单:

class ProcedureCrMetaForm(ModelForm):
    class Meta:
        model = SectionHeading
        fields = [
            'name',
            'default',
            'sortorder',
            'fieldtype',
            'procid'
        ]
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['name'].widget.attrs.update({'class': 'form-control'})
        self.fields['default'].widget.attrs.update({'class': 'form-control'})
        self.fields['sortorder'].widget.attrs.update({'class': 'form-control'})
        self.fields['fieldtype'].widget.attrs.update({'class': 'form-control'})

ProcedureCreationFormset = formset_factory(ProcedureCrMetaForm, extra=3)
ProcedureModificationFormset = modelformset_factory(SectionHeading, ProcedureCrMetaForm, 
    fields=('name', 'default', 'sortorder','fieldtype', 'procid'),
    can_delete=True,
    extra=0
    # widgets={"name": Textarea()}
    )

模板:

{% block content %} {% load widget_tweaks %}
<div class="container">
    {% if user.is_authenticated %}
    <div class="row my-1">
        <div class="col-sm-2">Name</div>
        <div class="col-sm-22">
            <input type="text" name="procedurename" class="form-control" placeholder="Enter name of procedure (E.g. DNE)"
                value="{{ template.title }}" />
        </div>
    </div>
    <div class="row my-1">
        <div class="col-sm-2">Description</div>
        <div class="col-sm-22">
            <input type="text" name="proceduredesc" class="form-control" placeholder="Enter description of procedure (E.g. Diagnostic Nasal Endoscopy)"
                value="{{ template.description }}" />
        </div>
    </div>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %} {{ formset.management_form }}
        <div class="row mt-3">
            <div class="col-sm-1">Select</div>
            <div class="col-sm-6">Heading</div>
            <div class="col-sm-8">Default (Normal description)</div>
            <div class="col-sm-2">Sort Order</div>
            <div class="col-sm-4">Type</div>
            <div class="col-sm-2">Action</div>
        </div>
        {% for form in formset %}
        <div class="row procrow" id="row{{ forloop.counter0 }}">
            <div class="" style="display: none;">{{ form.procid }}</div>
            <div class="col-sm-6">
                {{ form.name }}

            </div>

            <div class="col-sm-8">
                <div class="input-group">
                    {{ form.default }}
                </div>
            </div>
            <div class="col-sm-2">
                <div class="input-group">
                    {{ form.sortorder }}
                </div>
            </div>
            <div class="col-sm-4">
                <div class="input-group">
                    {{ form.fieldtype }}
                </div>
            </div>
            <div class="col-sm-2">
                <div class="input-group">
                    <div class="input-group-append">
                        <button id="add{{ forloop.counter0 }}" class="btn btn-success add-row">+</button>
                    </div>
                    <div class="input-group-append">
                        <button id="del{{ forloop.counter0 }}" class="btn btn-danger del-row">-</button>
                    </div>
                </div>
            </div>
        </div>
        {% endfor %} {% endif %}
        <div class="row my-3">
            <div class="col-sm-8"></div>
            <div class="col-sm-8">
                <div class="input-group">
                    <div class="input-group-append mx-1">
                        <button id="save_report" type="submit" class="btn btn-success"><i class="fal fa-shield-check"></i>
                            Save Report Format</button>
                    </div>
                    <div class="input-group-append mx-1">
                        <button id="save_report" type="button" class="btn btn-danger"><i class="fal fa-times-hexagon"></i>
                            Cancel</button>
                    </div>
                </div>
            </div>
            <div class="col-sm-8"></div>
        </div>

        <div>
            {% for dict in formset.errors %} {% for error in dict.values %} {{ error }} {% endfor %} {% endfor %}
        </div>
    </form>

</div>
{% endblock %}

我的数据显示如下(截图)。当按下删除按钮时,我使用javascript进行了更改,因此html变成了这样:

<div class="row procrow" id="row2" style="display: none;">
    <div class="" style="display: none;"><input type="hidden" name="form-2-procid" value="25" id="id_form-2-procid"></div>
    <div class="col-sm-6">
        <input type="text" name="form-2-name" value="a" maxlength="200" class="form-control" id="id_form-2-name">
    </div>
    <div class="col-sm-8">
        <div class="input-group">
            <input type="text" name="form-2-default" value="v" maxlength="1000" class="form-control" id="id_form-2-default">
        </div>
    </div>
    <div class="col-sm-2">
        <div class="input-group">
            <input type="number" name="form-2-sortorder" value="1000" class="form-control" id="id_form-2-sortorder">
        </div>
    </div>
    <div class="col-sm-4">
        <div class="input-group">
            <select name="form-2-fieldtype" class="form-control" id="id_form-2-fieldtype">
<option value="heading1" selected="">Heading1</option>

<option value="heading2">Heading2</option>
</select>
        </div>
    </div>
    <div class="col-sm-2">
        <div class="input-group">
            <div class="input-group-append">
                <button id="add2" class="btn btn-success add-row">+</button>
            </div>
            <div class="input-group-append">
                <button id="del2" class="btn btn-danger del-row">-</button>
            </div>
        </div>
    </div>

    <input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" checked=""></div>

提交数据时,我得到以下输出,并且数据不反映我所做的删除。它再次显示相同的内容。没有错误。但是我的编辑数据无法保存。

输出:

<bound method MultiValueDict.get of <QueryDict: {'csrfmiddlewaretoken': ['ka3avICLigV6TaMBK5a8zeVJlizhtsKW5OTDBLlYorKd7Iji9zRxCX2vvjBv6xKu'], 'form-TOTAL_FORMS': ['3'], 'form-INITIAL_FORMS': ['3'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['1000'], 'form-0-procid': ['23'], 'form-0-name': ['External ear canal'], 'form-0-default': ['Bilateral external ear canals appear normal. No discharge.'], 'form-0-sortorder': ['100'], 'form-0-fieldtype': ['heading1'], 'form-1-procid': ['24'], 'form-1-name': ['Tympanic membrane'], 'form-1-default': ['Tympanic membrane appears normal. Mobility not assessed.'], 'form-1-sortorder': ['500'], 'form-1-fieldtype': ['heading1'], 'form-2-procid': ['25'], 'form-2-name': ['a'], 'form-2-default': ['v'], 'form-2-sortorder': ['1000'], 'form-2-fieldtype': ['heading1'], 'form-2-DELETE': ['on']}>>
Form is valid
instances:[]
Deleted forms:
{'name': 'a', 'default': 'v', 'sortorder': 1000, 'fieldtype': 'heading1', 'procid': <SectionHeading: a [25]>, 'DELETE': True}

Screenshot

1 个答案:

答案 0 :(得分:2)

您实际上需要删除实例:调用deleted_objects后,循环浏览表单集的saved(commit=False)属性并删除它们。