如何在Django类视图中从HTML表单获取cleaned_data?
问题背景
我有一个使用类视图和手写HTML表单的Django应用,表单代码如下:
<form method="post" action="{% url 'personal-account' %}"> {% csrf_token %} <div class="page slide-page"> <div class="field"> <input type="text" placeholder="First name" class="input_1" name="first_name" size="1" value="{{ data.first_name }}"> <input type="text" placeholder="Last Name" class="input_2" name="last_name" size="1" value="{{ data.last_name }}"> </div> <div class="middle"> <input type="text" placeholder="Username" class="input_3" name="username" size="1" value="{{ data.username }}"> <input type="text" placeholder="Email" class="input_6" name="email" size="1" value="{{ data.email }}"> </div> <div class="last"> <input type="password" placeholder="Password" class="input_4" name="password" size="1" value="{{ data.password }}"> <input type="password" placeholder="Confirm" class="input_5" name="confirm_password" size="1" value="{{ data.confirm_password }}"> </div> <div class="field"> <button type="submit" class="submit-btn">Submit</button> </div> </div> </form>
视图代码:
class PersonalSignup(View): def post(self, request): return render(request, 'authentication/personal_signup.html') def get(self, request): return render(request, 'authentication/personal_signup.html')
现在需要从这些输入框(first_name、last_name等)中获取cleaned_data。
解决方案
因为你用的是手写HTML表单而非Django自带的Form类,有两种方式可以实现类似cleaned_data的清洗后数据获取:
方式一:手动验证清洗数据
直接从request.POST提取原始数据,自行编写验证和清洗逻辑:
修改PersonalSignup视图的post方法:
class PersonalSignup(View): def post(self, request): # 提取并初步清洗原始数据 raw_data = { 'first_name': request.POST.get('first_name', '').strip(), 'last_name': request.POST.get('last_name', '').strip(), 'username': request.POST.get('username', '').strip(), 'email': request.POST.get('email', '').strip(), 'password': request.POST.get('password', ''), 'confirm_password': request.POST.get('confirm_password', '') } cleaned_data = {} errors = {} # 验证必填字段 for field in ['first_name', 'last_name', 'username', 'email', 'password', 'confirm_password']: if not raw_data[field]: errors[field] = "此字段不能为空" else: cleaned_data[field] = raw_data[field] # 验证邮箱格式 if cleaned_data.get('email'): from django.core.validators import validate_email from django.core.exceptions import ValidationError try: validate_email(cleaned_data['email']) except ValidationError: errors['email'] = "邮箱格式无效" # 验证密码一致性 if cleaned_data.get('password') != cleaned_data.get('confirm_password'): errors['password'] = "两次输入的密码不一致" # 根据验证结果处理 if errors: return render(request, 'authentication/personal_signup.html', {'data': raw_data, 'errors': errors}) else: # 这里可使用cleaned_data执行后续操作(如创建用户) return render(request, 'authentication/personal_signup.html', {'success': True}) def get(self, request): return render(request, 'authentication/personal_signup.html')
模板中可添加错误提示(示例):
<div class="field"> <input type="text" placeholder="First name" class="input_1" name="first_name" size="1" value="{{ data.first_name }}"> {% if errors.first_name %} <span style="color:red;">{{ errors.first_name }}</span> {% endif %} <input type="text" placeholder="Last Name" class="input_2" name="last_name" size="1" value="{{ data.last_name }}"> {% if errors.last_name %} <span style="color:red;">{{ errors.last_name }}</span> {% endif %} </div>
方式二:改用Django Form类(推荐)
这是Django的标准实践,自动处理验证和清洗,代码更简洁可靠:
1. 定义Form类
在应用目录下创建forms.py:
from django import forms class PersonalSignupForm(forms.Form): first_name = forms.CharField(max_length=100, required=True) last_name = forms.CharField(max_length=100, required=True) username = forms.CharField(max_length=150, required=True) email = forms.EmailField(required=True) password = forms.CharField(widget=forms.PasswordInput, required=True) confirm_password = forms.CharField(widget=forms.PasswordInput, required=True) # 自定义密码匹配验证 def clean(self): cleaned_data = super().clean() password = cleaned_data.get('password') confirm_pwd = cleaned_data.get('confirm_password') if password and confirm_pwd and password != confirm_pwd: raise forms.ValidationError("两次输入的密码不一致") return cleaned_data
2. 修改类视图
from .forms import PersonalSignupForm class PersonalSignup(View): def post(self, request): form = PersonalSignupForm(request.POST) if form.is_valid(): # 获取自动清洗后的合法数据 cleaned_data = form.cleaned_data # 执行后续操作(如创建用户) return render(request, 'authentication/personal_signup.html', {'success': True}) else: # 将含错误的表单传回模板 return render(request, 'authentication/personal_signup.html', {'form': form}) def get(self, request): form = PersonalSignupForm() return render(request, 'authentication/personal_signup.html', {'form': form})
3. 调整模板(可选)
保留手写样式的同时绑定表单数据和错误提示:
<form method="post" action="{% url 'personal-account' %}"> {% csrf_token %} <div class="page slide-page"> <div class="field"> <input type="text" placeholder="First name" class="input_1" name="first_name" size="1" value="{{ form.first_name.value|default_if_none:'' }}"> {% if form.first_name.errors %} <span style="color:red;">{{ form.first_name.errors.0 }}</span> {% endif %} <input type="text" placeholder="Last Name" class="input_2" name="last_name" size="1" value="{{ form.last_name.value|default_if_none:'' }}"> {% if form.last_name.errors %} <span style="color:red;">{{ form.last_name.errors.0 }}</span> {% endif %} </div> <!-- 其他字段按此逻辑调整 --> <div class="field"> <button type="submit" class="submit-btn">Submit</button> </div> </div> </form>
内容的提问来源于stack exchange,提问作者Tadej Tilinger
相关产品推荐
相关产品推荐

