首页 > 解决方案 > 成功提交表单后重定向后的Django Form为空

问题描述

我有一个名为coursesurl的模板http://127.0.0.1:8000/gradebook/courses/。此模板列出现有Course对象加载CourseForm表单。表单成功创建了新对象。

addassessment如果我使用 url转到模板http://127.0.0.1:8000/gradebook/addassessment/7/,它会正确加载AssessmentForm. 我想提交此表单,然后返回到之前的courses模板。提交并保存对象,AssessmentForm但是当它重定向回courses模板时,CourseForm不会加载。courses模板加载,期望 html 正确加载,而不是表单字段。我注意到此页面的 url 仍然是http://127.0.0.1:8000/gradebook/addassessment/7/而不是../gradebook/courses/

app_name = 'gradebook'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('signup/', SignUpView.as_view(), name='signup'),
    path('courses/', views.courses, name='courses'),
    path('classroom/', views.classroom, name='classroom'),
    path('objective/<int:course_id>/', views.addobjective, name='addobjective'),
    path('addassessment/<int:course_id>/', views.addassessment, name='addassessment'),
]

#urls.py project
urlpatterns = [
    path('', TemplateView.as_view(template_name='home.html'), name='home'),
    path('admin/', admin.site.urls),
    path('gradebook/', include('gradebook.urls')),
    path('gradebook/', include('django.contrib.auth.urls')),
]

#models.py
class Course(models.Model):
    course_name = models.CharField(max_length=10)

class Classroom(models.Model):
    classroom_name = models.CharField(max_length=10)
    course = models.ForeignKey(Course, on_delete=models.CASCADE)

class Assessment(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    assessment_name = models.CharField(max_length=10)
    objectives = models.ManyToManyField('Objective')

class Objective(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    objective_name = models.CharField(max_length=10)
    objective_description = models.CharField(max_length=30)
    
#views.py
def courses(request):
    course_list = Course.objects.order_by('course_name')
    context = {'course_list': course_list}

    if request.method == 'POST':
        details = CourseForm(request.POST)

        if details.is_valid():
            course = details.save(commit=False)
            course.save()

            form = CourseForm(None)
            context['form'] = form
            return render(request, "gradebook/courses.html", context)

        else:
            context['form'] = details
            return render(request, "gradebook/courses.html", context)

    else:
        form = CourseForm(None)
        context['form'] = form
        return render(request, "gradebook/courses.html", context)
        
def addassessment(request, course_id):
    course_list = Course.objects.order_by('course_name')
    this_course = Course.objects.get(id=course_id)
    objectives = Objective.objects.filter(course=this_course).order_by('objective_name')
    context = {'this_course': this_course}
    context['objectives'] = objectives
    context['course_list'] = course_list

    if request.method == 'POST':
        form = AssessmentForm(request.POST)

        if form.is_valid():
            assess = form.save(commit=False)
            # save the course that the objective belongs to
            assess.course = this_course
            assess.save()
            form.save_m2m()

            return render(request, "gradebook/courses.html", context)

        else:
            context['form'] = form
            return render(request, "gradebook/addassessment.html", context)

    else:
        form = AssessmentForm(None)
        form.fields["objectives"].queryset = Objective.objects.filter(course=this_course)
    context['form'] = form
    return render(request, "gradebook/addassessment.html", context)
    
#forms.py
class AssessmentForm(ModelForm):
    class Meta:
        model = Assessment
        fields = ('assessment_name', 'objectives',)

class CourseForm(ModelForm):
    class Meta:
        model = Course
        fields = ["course_name"]

    def clean(self):
        super(CourseForm, self).clean()

        course_name = self.cleaned_data.get('course_name')
        if course_name and Course.objects.filter(course_name__iexact=course_name).exists():
            self.add_error(
                'course_name', 'A course with that course name already exists.')
        if len(course_name) > 10:
            self.add_error(
                'Your course name cannot be longer than 10 characters')

        return self.cleaned_data
    
#courses template: course.html
<div class="container">
    <div class="row">
        <div class="twelve columns">
            <h1>Courses</h1>
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            {% if course_list %}
                <ul>
                {% for course in course_list %}
                    <li><div class = "row">
                        <div class = "col-md-3">
                            {{ course.course_name }}
                        </div>
                        </div></li>
                {% endfor %}
                </ul>
            {% else %}
                <p>No Courses are available.</p>
            {% endif %}
        </div>
    </div>
    <div class="row">
        <div class="col-md-3">
            <p>Create a new course</p>
        </div>
        <div class="col-md-3">
            <form action="{% url 'gradebook:courses' %}" method="post">
            {% csrf_token %}
            {{ form.as_p }}
                <div class="form-group">
                    <button type="submit" class="btn btn-primary">
                        Submit
                    </button>
                </div>
            </form>
        </div>
    </div>

</div>

#addassessment template: addassessment.html
<div class="container">
  <div class="row">
    <div class="twelve columns">
      <h1>{{ this_course }}</h1>
    </div>
  </div>
  <div class="row">
    <div class="col-md-3">
      <p>Add an assessment to your class</p>
    </div>
    <div class="col-md-3">
      <div class="form-group">
      <form action="" method="post">
        {% csrf_token %} {{ form|crispy }}
        <div class="form-group">
          <button type="submit" class="btn btn-secondary">Submit</button>
        </div>
      </form>
    </div>
    </div>
  </div>
</div>

没有错误消息。

标签: djangodjango-forms

解决方案


http://127.0.0.1:8000/gradebook/addassessment/7/当您在将发布请求发送回您的 addassessment视图功能以处理您知道的表单时提交您的评估表时。结果,url 仍然是相同的,这就是您所看到的。

如果您的评估表以您所写的方式有效,我建议您不要退回课程模板

#inside addassessment view function
return render(request, "gradebook/courses.html", context)

如果您只是想在成功保存评估表后重定向到课程视图,我建议使用重定向快捷方式。

# add to your import
from django.shortcuts import render, redirect

#inside addassessment view function - replacing "return render(request, "gradebook/courses.html", context)"
return redirect(courses)

这会将您的请求对象发送到课程视图功能。重定向将使用 GET 操作而不是帖子,因此您只会看到通常在http://127.0.0.1:8000/gradebook/courses/. 这也将是网址!


推荐阅读