django 表单未显示,根本原因在于误将 `forms.textarea`(一个 widget)直接用作字段类型;应改用 `forms.charfield` 并通过 `widget` 参数指定 textarea,才能使表单字段正常渲染并绑定数据。
在 Django 中,forms.Textarea 是一个 Widget(控件),用于定义字段在 HTML 中的渲染方式,但它本身 不是字段类。而你在 forms.py 中错误地将其作为字段声明:
# ❌ 错误写法:Textarea 是 widget,不能直接当字段用
text = forms.Textarea(attrs={'class': 'form-control', 'rows': '4'})这会导致 Django 无法识别为有效表单字段,因此 {{ form2 }} 在模板中不渲染任何输入控件(仅输出空字符串),最终页面只显示硬编码的 HTML 和提交按钮。
✅ 正确做法是:使用语义明确的字段类(如 CharField),并通过 widget 参数注入 Textarea 控件:
# ✅ 正确写法:CharField + Textarea widget
class BulkModulImport(forms.Form):
text = forms.CharField(
widget=forms.Textarea(attrs={
'class': 'form-control',
'rows': '4',
'placeholder': '每行一个模块名称,例如:Mathematik I...'
})
)这样,Django 才能:
⚠️ 其他注意事项:
完整修正后的最小可运行示例:
# forms.py
from django import forms
class BulkModulImport(forms.Form):
text = forms.CharField(
widget=forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': '请输入模块列表,每行一个'
})
)
# views.py(精简版)
from django.shortcuts import re
nder
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.urls import reverse
import re
from django.utils import timezone
from .forms import BulkModulImport
from .models import Modul
def bulk_modul_import(request):
if request.method == "POST":
form = BulkModulImport(request.POST)
if form.is_valid():
raw_text = form.cleaned_data['text']
lines = raw_text.split('\n')
for line in lines:
cleaned_line = re.sub(r'\s*\d*$', '', line.replace(' .', '')).strip()
if "Module der Lehreinheit" not in cleaned_line and cleaned_line:
Modul.objects.create(
title=cleaned_line,
proposer=request.user,
dozent=None,
created_date=timezone.now(),
description=""
)
messages.success(request, '批量导入成功!')
return HttpResponseRedirect(reverse('modul_list'))
else:
form = BulkModulImport() # 注意:变量名统一为 form,模板中仍用 form2 或改为 form
return render(request, 'score/bulk_import.html', {'form2': form})最后检查模板是否加载无误——确保 {% csrf_token %} 存在(你已包含),且未因 JavaScript 阻止表单提交。调试时可在视图中临时添加 print(form) 和 print(form.errors) 辅助定位问题。