Django循环生成表单时AJAX仅获取最后一个表单数据问题求助
Django循环生成多表单,AJAX提交仅获取最后一个表单数据
在Django模板中通过for循环生成多个表单,使用AJAX无刷新提交时,后端始终只能获取到最后一个表单的数据。相关代码如下:
HTML代码
{% for post in post_list %} <form class = "f_form" id="f_form" name = "myForm" method="POST"> {% csrf_token %} {{ form.as_p }} <button type="submit" class="add">Submit</button> </form> {% endfor %}
JQuery代码
<script type="text/javascript"> $(document).ready(function(){ $(document).on('click','.add',function (event) { event.preventDefault(); var element = $(this); $.ajax({ url: '{% url "webscraper-favorited" %}', method: 'post', data:element.parent('.f_form').serialize(), success: function(data){ $('#message').html(data); } }); return false; }); }); </script>
views.py代码
def favorited(request): if request.method == 'POST': favorited = request.POST.get('favorited') favorites.append(favorited) print(favorited) context = { 'favorites' : favorites, } return render(request, 'webscraper/favorited.html', context)
问题原因
- 表单ID重复:循环生成的所有表单共用同一
id="f_form",违反HTML唯一ID规则,可能导致DOM选择逻辑异常。 - 缺少唯一标识:每个表单未绑定对应
post的唯一标识,后端无法区分提交来源;若表单字段名称完全一致,序列化时可能出现数据覆盖。 - 选择器不健壮:
parent('.f_form')仅查找直接父元素,若按钮外层有嵌套结构,会无法正确定位到目标表单。
解决方案
1. 修正HTML模板
- 移除重复ID,或基于
post.id生成唯一ID; - 添加隐藏字段传递
post的唯一标识,明确后端处理目标; - 保留
class="f_form"用于JS选择。
{% for post in post_list %} <form class="f_form" name="myForm_{{ post.id }}" method="POST"> {% csrf_token %} {{ form.as_p }} <!-- 新增隐藏字段传递post唯一标识 --> <input type="hidden" name="post_id" value="{{ post.id }}"> <button type="submit" class="add">Submit</button> </form> {% endfor %}
2. 优化AJAX代码
- 使用
closest('.f_form')替代parent('.f_form'),确保不受嵌套结构影响,精准定位当前表单; - 保持事件委托写法,兼容动态生成的表单元素。
<script type="text/javascript"> $(document).ready(function(){ $(document).on('click','.add',function (event) { event.preventDefault(); // 向上查找最近的表单元素 var $form = $(this).closest('.f_form'); $.ajax({ url: '{% url "webscraper-favorited" %}', method: 'post', data: $form.serialize(), success: function(data){ $('#message').html(data); } }); return false; }); }); </script>
3. 完善后端视图
- 接收
post_id字段,明确处理对应post的收藏操作; - 替换全局
favorites列表为request.session,避免多用户数据混乱。
def favorited(request): if request.method == 'POST': # 获取提交的post标识和业务字段 post_id = request.POST.get('post_id') favorited = request.POST.get('favorited') # 使用session存储当前用户的收藏数据 favorites = request.session.get('favorites', []) if post_id not in favorites: favorites.append(post_id) request.session['favorites'] = favorites print(f"收藏的post ID: {post_id}, 状态值: {favorited}") context = { 'favorites': request.session.get('favorites', []), } return render(request, 'webscraper/favorited.html', context)
内容的提问来源于stack exchange,提问作者dan-yee-yee
相关产品推荐
相关产品推荐

