Django 2.1提交HTML表单到数据库时出现URL不存在404错误
解决404错误及动态字段实现方案
一、先搞定404错误
你的404问题根源在于URL配置、视图参数和模板调用三者不匹配,一步步修正:
- 修正URL配置
test视图需要接收startup_id参数,所以URL规则要改成带参数的形式:
# urls.py path('test/<int:startup_id>/', views.test, name='test'),
- 修正模板中的表单action
模板里的表单action没有传递startup_id,要补上参数,同时视图要把该参数传给模板:
<!-- test.html --> <form id="add-extra" class="form" method="post" action = "{% url 'test' startup_id=startup_id %}">{% csrf_token %}
对应的视图修改:
# views.py def test(request, startup_id): # 用get_object_or_404处理不存在的startup,避免报错 startup = get_object_or_404(Startup, pk=startup_id) if request.method == 'POST': # 后续处理逻辑 return render(request, 'test.html', {'startup_id': startup_id, 'startup': startup})
- 修正视图中外键关联的错误
原来的e = Startup.objects.values('startup_name')是查询所有Startup的名称,完全不符合需求,要改成用传入的startup_id获取对应的Startup实例:
# views.py中test视图的POST部分 if request.method == 'POST': # 注意表单里的input name是candidate_name,要和这里对应 na = request.POST.get("candidate_name") po = request.POST.get("position") qu = request.POST.get("qualification") # 用获取到的startup实例关联外键 ref = Team(name=na, position=po, qualification=qu, str_team=startup) ref.save() return redirect('str_dashboard')
二、用HTML+jQuery实现动态添加字段
接下来实现动态添加团队成员行的功能,简化UI:
- 调整test.html的表格结构
给tbody加ID方便定位,同时给操作按钮添加类名,输入框用数组格式的name方便后端批量处理:
<table class="table"> <thead> <tr> <th>Name</th> <th>Position</th> <th>Qualification</th> <th>Action</th> </tr> </thead> <tbody id="team-rows"> <!-- 初始行 --> <tr> <td><input class="form-control" type="text" name="team_members[][name]" required/></td> <td><input class="form-control" type="text" name="team_members[][position]" required/></td> <td><input class="form-control" type="text" name="team_members[][qualification]" required/></td> <td> <button class="btn btn-primary add-row" type="button" style="margin-top:4px;margin-left:15px;background-color:rgb(24,130,7);"> <i class="fas fa-plus"></i> </button> <button class="btn btn-danger remove-row" type="button" style="margin-top:4px;margin-left:5px;"> <i class="fas fa-minus"></i> </button> </td> </tr> </tbody> </table>
- 添加jQuery脚本
在模板底部引入jQuery并添加动态行逻辑(确保页面已加载jQuery):
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script> $(document).ready(function() { // 添加新行 $('#team-rows').on('click', '.add-row', function() { var newRow = $(this).closest('tr').clone(); // 清空克隆行的输入框内容 newRow.find('input').val(''); // 添加到表格末尾 $('#team-rows').append(newRow); }); // 删除行(至少保留一行) $('#team-rows').on('click', '.remove-row', function() { if ($('#team-rows tr').length > 1) { $(this).closest('tr').remove(); } }); }); </script>
- 修改后端批量处理数据
现在可以一次性接收所有团队成员数据,批量创建Team对象:
# views.py中test视图的POST部分 if request.method == 'POST': # 获取所有成员的字段数据 names = request.POST.getlist('team_members[][name]') positions = request.POST.getlist('team_members[][position]') qualifications = request.POST.getlist('team_members[][qualification]') # 遍历批量创建,跳过空字段 for name, pos, qual in zip(names, positions, qualifications): if name.strip() and pos.strip() and qual.strip(): Team.objects.create( name=name, position=pos, qualification=qual, str_team=startup ) return redirect('str_dashboard')
三、额外优化建议
- 表单提交按钮的type应该是
submit,而不是post:
<button class="btn btn-primary text-center border rounded d-lg-flex justify-content-lg-end align-items-lg-center form-btn" type="submit" style="margin-left:1040px;padding:6px;">SAVE </button>
- 在
startupform的clean方法中,应该检查当前用户的Startup是否重名(如果允许不同用户有相同名称的Startup的话),避免误判:
def clean(self): super().clean() startup_name = self.cleaned_data.get('startup_name') # 只检查当前用户的Startup startup_qs = Startup.objects.filter(author= self.instance.author, startup_name=startup_name) if self.instance.pk: startup_qs = startup_qs.exclude(pk=self.instance.pk) if startup_qs.exists(): raise forms.ValidationError('This Startup Already Exist!')
内容的提问来源于stack exchange,提问作者Mohammad Al Blooshi
相关产品推荐
相关产品推荐

