如何在Django表单中自动填充slug和用户字段并解决写入失败问题
问题分析
你的代码核心问题是表单验证未通过:因为slug和author是模型必填字段,前端提交的POST数据里这两个字段为空,导致form.is_valid()返回False,后续的保存逻辑根本没执行。再加上视图没有区分GET/POST请求,GET请求时直接用空的request.POST初始化表单,也会导致表单状态异常。
解决方案
1. 调整表单定义(forms.py)
既然slug和author是自动填充的,不需要用户输入,直接从表单字段中移除,只保留需要用户填写的test_name:
from django import forms from .models import Test class AddTestForm(forms.ModelForm): class Meta: model = Test fields = ['test_name'] # 只保留用户需要输入的字段
2. 修复视图逻辑(views.py)
- 区分GET/POST请求:GET时生成空表单,POST时处理提交
- 强制用户登录,避免
request.user是匿名用户导致外键错误 - 填充
slug和author后保存,同时处理slug重复的情况
from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.utils.text import slugify from .forms import AddTestForm @login_required # 强制用户登录,避免匿名用户提交 def ask_test_name(request): if request.method == 'POST': form = AddTestForm(request.POST) if form.is_valid(): test = form.save(commit=False) # 自动填充slug test.slug = slugify(test.test_name) # 处理slug重复,避免违反unique约束 original_slug = test.slug counter = 1 while Test.objects.filter(slug=test.slug).exists(): test.slug = f"{original_slug}-{counter}" counter += 1 # 填充当前登录用户为作者 test.author = request.user test.save() return redirect('some_success_url') # 提交成功后跳转,避免重复提交 else: form = AddTestForm() # GET请求时生成空表单 return render(request, 'app/ask_test_name.html', {'form': form})
3. 简化模板(ask_test_name.html)
不需要手动写输入框,直接用Django表单的渲染方法,既简洁又避免字段不匹配:
<form action="{% url 'ask_test_name' %}" method="post"> {% csrf_token %} {{ form.as_p }} <!-- 自动渲染表单字段,这里只会显示test_name输入框 --> <p><button type="submit">Create</button></p> </form>
额外说明
- 如果需要自定义
test_name字段的样式,可以单独渲染字段:<p>{{ form.test_name.label_tag }} <input type="text" name="{{ form.test_name.name }}" required></p> - 必须确保用户已登录,否则
request.user是匿名用户,无法填充author字段(@login_required装饰器会自动跳转到登录页)。
内容的提问来源于stack exchange,提问作者lightfly
相关产品推荐
相关产品推荐

