首页 > 解决方案 > Django - 如何单独编辑和提交多个表单然后呈现回同一页面?

问题描述

所以我正在构建这个学习日志应用程序,用户可以在其中创建多个主题。我正在尝试创建一个页面,用户可以在其中编辑/保存更改/删除他们的主题名称。我在视图功能中的逻辑edit_topic是用savedelete按钮的形式显示原始主题,下面的代码或随意检查GitHub Repo

视图.py

def edit_topics(request, topic_pk=None):
    '''edit existing topics mainly the names'''
    # modify the model data according to the request method and name
    if request.method == 'POST' and topic_pk != None:
        if 'save' in request.POST:
            topic_to_change = get_object_or_404(Topic, pk=topic_pk)
            form = TopicForm(instance=topic_to_change, data=request.POST)
            if form.is_valid():
                form.save()
        elif 'delete' in request.POST:
            topic_to_delete = get_object_or_404(Topic, pk=topic_pk)
            topic_to_delete.delete()
        return redirect('learning_logs:edit_topics')

    # get the original/modified data passing to render
    topics = Topic.objects.all()
    topic_lst = []
    for topic in topics:
        form = TopicForm(instance=topic)
        topic_lst.append(form)
    context = {'topics': topics, 'topic_lst': topic_lst}
    return render(request, 'learning_logs/edit_topics.html', context)

编辑主题.html

{% extends 'learning_logs/base.html' %}

{% block content %}
<section class="container">
    <h3>Topics you have created</h3>
    <ul class="">
        {% for form in topic_lst %}
        <li class="mb-5">
            <form class="d-flex align-items-center" 
action="{% url 'learning_logs:edit_topics' form.instance.pk %}" method="POST">
                {% csrf_token %}
                {{ form.as_p }}
                <button class="btn btn-primary" name="submit">save</button>
                <button class="btn btn-danger" name="delete">delete</button>
            </form>
        </li>
        {% endfor %}
    </ul>
    <a class="btn btn-info" href="{% url 'learning_logs:topics' %}">Done</a>
</section>

{% endblock content %}

网址.py

from django.urls import path
from . import views

app_name="learning_logs"
urlpatterns = [
    path('', views.index, name='index'),



    path('topics/', views.topics, name='topics'),
    path('topics/edit/', views.edit_topics, name='edit_topics'),



    path('new_topic/', views.new_topic, name='new_topic'),
    path('topic_<int:topic_pk>/', views.topic, name='topic'),
    path('topic_<int:topic_pk>/new_entry/', views.new_entry, name='new_entry'),
    path('topic_<int:topic_pk>/entry_<int:entry_pk>/', views.entry, name='entry'),
    path('topic_<int:topic_pk>/entry_<int:entry_pk>/edit_entry/', views.edit_entry, name='edit_entry'),
]

但是,我认为可能存在一些逻辑错误,它不断提高NoReverseMatch(msg) django.urls.exceptions.NoReverseMatch: Reverse for 'edit_topics' with arguments '(1,)' not found. 1 pattern(s) tried: ['topics/edit$']

如果我form.instance.pkedit_topics.html文件中删除,则不会引发错误。但因此,if视图函数中的逻辑不会采取行动......我对编程相当陌生,我敢肯定也有一些逻辑错误 -

我正在努力处理topic_pk视图函数中的可选参数,因为我不确定如何正确传递它。

理想情况下,我希望用户可以在这个页面上一个一个地编辑、保存或删除主题,当他们点击savedelete页面会重定向回这个视图并呈现更新的主题文本。最后,当他们完成后,他们可以点击最后的Done按钮......

请帮忙!谢谢!!

随时查看GitHub Repo 以获取 Learning_Log 应用程序

标签: pythondjangoformslogic

解决方案


像这样更新您的网址:

path('topics/edit/', views.edit_topics, name='edit_topics'),
path('topics/edit/<int:topic_pk>/', views.edit_topics, name='edit_topic'),

在 html 中,更改这一行:

<form class="d-flex align-items-center" action="{% url 'learning_logs:edit_topic' form.instance.pk %}" method="POST">
                                                                     ^^^^^^^^^^^

在这里,我所做的是,有 2 个 url 指向同一个视图,一个有topic_pk,另一个没有。


推荐阅读