无法 edit/delete 现有格式

Unable to edit/delete existing formets

我是新来的。在过去的几天里,我一直在研究这个问题。有人可以帮帮我吗?

问题:无法edit/delete现有的表单集

我在一个视图中有 1 个表单和 2 个表单集。我可以成功创建所有 3 个。

Template rendering 1 form and 2 formsets

此外,我可以 edit/delete 表单,但不能使用 2 个表单集。

models.py

class Component(models.Model):
  ...

class ComponentImage(models.Model):
  component = models.ForeignKey(Component, on_delete=models.CASCADE, related_name='componentimage')
  image = models.ImageField(upload_to='component_pics')
  caption = models.CharField(max_length=100, null=True, blank=True)

class ComponentWeblink(models.Model):
  component = models.ForeignKey(Component, on_delete=models.CASCADE, related_name='componentweblink')
  url = models.URLField()
  caption = models.CharField(max_length=100, null=True, blank=True)

views.py

def component_create(request):
template = 'component/component_add.html'
if request.method == 'GET':
    form = ComponentForm()
    images = ImageFormset(queryset=ComponentImage.objects.none(), prefix='images')
    links = WeblinkFormset(queryset=ComponentWeblink.objects.none(), prefix='links')
elif request.method == 'POST':
    form = ComponentForm(request.POST)
    images = ImageFormset(request.POST, request.FILES, prefix='images')
    links = WeblinkFormset(request.POST, prefix='links')
    if form.is_valid() and images.is_valid() and links.is_valid():
        component = form.save(commit=False)
        component.updated_by = request.user
        component.save()
        for form in images:
            if form.has_changed():
                componentimage = form.save(commit=False)
                componentimage.component = component
                componentimage.updated_by = component.updated_by
                try:
                    componentimage.save()
                except ValueError:
                    pass
        for form in links:
            if form.has_changed():
                componentweblink = form.save(commit=False)
                componentweblink.component = component
                componentweblink.updated_by = component.updated_by
                componentweblink.save()
        messages.success(request, 'Component successfully created.')
        return HttpResponseRedirect(reverse_lazy('component:component_detail', args=(component.pk,)))
return render(request, template, {
    'form': form,
    'images': images,
    'links': links,
})

def component_update(request, pk):
obj = get_object_or_404(Component, id=pk)
template = 'component/component_update.html'
if request.method == 'GET':
    form = ComponentForm(instance=obj)
    images = ImageFormset(instance=obj, prefix='images')
    links = WeblinkFormset(instance=obj, prefix='links')
elif request.method == 'POST':
    form = ComponentForm(request.POST or None, instance=obj)
    images = ImageFormset(request.POST or None, request.FILES or None, instance=obj, prefix='images') 
    links = WeblinkFormset(request.POST, instance=obj, prefix='links')
    if form.is_valid() and images.is_valid() and links.is_valid():
        component = form.save(commit=False)
        component.updated_by = request.user
        component.save()
        for form in images:
            if form.has_changed():  
                componentimage = form.save(commit=False)
                componentimage.component = component
                componentimage.updated_by = component.updated_by
                try:
                    componentimage.save()
                except ValueError:  
                    pass
        for form in links:
            if form.has_changed():  
                componentweblink = form.save(commit=False)
                componentweblink.component = component
                componentweblink.updated_by = component.updated_by
                componentweblink.save()
        messages.warning(request, 'Component successfully updated.')
        return HttpResponseRedirect(reverse_lazy('component:component_detail', args=(component.pk, ))) #trailing comma is required for single-item tuples to disambiguate defining a tuple or an expression surrounded by parentheses
return render(request, template, {
    'form': form,
    'images': images,
    'links': links,
})

template.html(用于更新视图)

{% block content %}

<script type="text/javascript" src="{% static 'js/jquery.formset.js' %}"></script>
<script type="text/javascript">
    $(function() {
        $('#images tbody tr').formset({
            prefix: '{{ images.prefix }}',
            formCssClass: 'dynamic-images'
        });
        $('#links tbody tr').formset({
            prefix: '{{ links.prefix }}',
            formCssClass: 'dynamic-links'
        });

    })
</script>

<div class="row justify-content-center">
    <form method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <fieldset class="form-group">
            <legend style="text-align:center" class="border-bottom mb-4">
                Update Component
            </legend>
            <h5 style="text-align:center" >Data</h5>
            {% include 'snippets/form.html' %}
            <hr>
            <h5 style="text-align:center" >Images</h5>
            <table class="col col-md-12" id="images">
                <tbody>
                    {{ images.management_form }}
                    {{ images.non_form_errors }}
                    {% for form in images.forms %}
                        <tr>
                           <td class="px-0 py-0 form-control{% if form.image.errors %} is-invalid{% else %} border-0{% endif %}">{{ form.image }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.image.non_field_errors }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.image.errors }}</td>
                           <td class="px-0 py-0 form-control{% if form.image.errors %} is-valid{% else %} border-0{% endif %}">{{ form.caption }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.caption.non_field_errors }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.caption.errors }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>

            <hr>
            <h5 style="text-align:center" >Weblinks</h5>
            <table class="col col-md-12" id="links" border="0" cellpadding="0">
                <tbody>
                    {{ links.management_form }}
                    {{ links.non_form_errors }}
                    {% for form in links.forms %}
                        <tr>
                           <td class="px-0 py-0 form-control{% if form.url.errors %} is-invalid{% else %} border-0{% endif %}">{{ form.url }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.url.errors }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.url.non_field_errors }}</td>
                           <td class="px-0 py-0 form-control{% if form.url.errors %} is-valid{% else %} border-0{% endif %}">{{ form.caption }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.caption.errors }}</td>
                           <td class="border-0 px-0 py-0 form-control" style="color:red">{{ form.caption.non_field_errors }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>

            <br>
            <button class="btn btn-primary" type="submit">
                Update
            </button>
            <a class="btn btn-outline-secondary" href="{% if request.GET.next %}{{ request.GET.next }}{% else %}{% url 'component:components_list' %}{% endif %}">
                Cancel
            </a>
        </fieldset>
    </form>
</div>

{% endblock content %}

请帮忙。谢谢

使用 VSCode 调试器,根据朋友的建议。问题是没有添加 id (hidden_fields).

我在更新模板中添加了这个:

{% for form in images.forms %}
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}

{% for form in links.forms %}
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}

还将 image.has_changed() 添加到 views.py 以避免接受空图像字段。

for image in images:
    if image.is_valid() and image.has_changed():
        try:
            image.save()
        except ValueError:
            pass