【问题标题】:Unable to edit/delete existing formets无法编辑/删除现有格式
【发布时间】:2020-07-21 02:30:07
【问题描述】:

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

问题:无法编辑/删除现有表单集

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

Template rendering 1 form and 2 formsets

另外,我可以编辑/删除表单,但不能使用 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 %}

请帮忙。谢谢

【问题讨论】:

    标签: django django-forms django-views formset inline-formset


    【解决方案1】:

    根据朋友的建议,使用了 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      相关资源
      最近更新 更多