You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在两个不同模板中分步填充Django表单?

Django跨模板分步初始化模型字段解决方案

现有代码回顾

models.py

class Person(models.Model):
    Person_ID = models.AutoField(blank=False, primary_key=True)
    p_SSN = models.CharField(blank=False, null=False, max_length=10)
    p_fName = models.CharField(null=False, blank=False, max_length=15)
    p_lName = models.CharField(null=False, blank=False, max_length=25)
    p_phoneNum = models.CharField(null=False, blank=False, max_length=11)
    p_birthDate = models.DateField(null=False, blank=False)
    p_Email = models.EmailField(null=False, blank=False, unique=True)
    p_Password = models.CharField(null=False, blank=False, max_length=20)

当前PersonForm

class PersonForm(forms.ModelForm):
    p_fName = forms.CharField(max_length=15)
    p_lName = forms.CharField(max_length=25)
    p_SSN = forms.CharField(max_length=10)
    p_phoneNum = forms.CharField(max_length=11)
    p_birthDate = forms.DateField()
    p_Email = forms.EmailField(max_length=255)
    p_Password = forms.CharField(max_length=255)

    class Meta:
        model = Person
        fields = ['p_fName', 'p_lName', 'p_SSN', 'p_phoneNum', 'p_birthDate', 'p_Email', 'p_Password']

当前视图new_student

def new_student(request):
    newStudentForm = PersonForm(request.POST or None)
    if newStudentForm.is_valid():
        newStudentForm.save()
    return render(request,
                  'signUp_student.html',
                  {'form': newStudentForm})

第一步模板signUp_student.html

<form action="{% url 'new_student' %}" method="post">
    {% csrf_token %}
    <label for="firstName">First Name</label><br>
    {{ form.p_fName }}<br>
    <label for="lastName">Last Name</label><br>
    {{ form.p_lName }}<br>
    <label for="firstName">SSN Code</label><br>
    {{ form.p_SSN }}<br>
    <label for="birthdate">Birthdate</label><br>
    {{ form.p_birthDate }}<br>
    <label for="phoneNumber">Phone Number</label><br>
    {{ form.p_phoneNum }}<br><br>
    <button type="submit">Sign up</button>
</form>

分步实现方案

1. 拆分表单类

创建两个独立表单,分别对应两步需填写的字段:

# forms.py
from django import forms
from .models import Person

class PersonBasicForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = ['p_fName', 'p_lName', 'p_SSN', 'p_phoneNum', 'p_birthDate']
        widgets = {
            'p_birthDate': forms.DateInput(attrs={'type': 'date'}),
        }

class PersonAuthForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = ['p_Email', 'p_Password']
        widgets = {
            'p_Password': forms.PasswordInput(),
        }

2. 编写分步视图函数

通过session暂存第一步的有效数据,再与第二步数据合并创建实例:

# views.py
from django.shortcuts import render, redirect
from .forms import PersonBasicForm, PersonAuthForm
from .models import Person
from django.contrib.auth.hashers import make_password

def signup_step1(request):
    if request.method == 'POST':
        form = PersonBasicForm(request.POST)
        if form.is_valid():
            request.session['person_basic_data'] = form.cleaned_data
            return redirect('signup_step2')
    else:
        form = PersonBasicForm()
    return render(request, 'signup_step1.html', {'form': form})

def signup_step2(request):
    if 'person_basic_data' not in request.session:
        return redirect('signup_step1')
    
    if request.method == 'POST':
        auth_form = PersonAuthForm(request.POST)
        if auth_form.is_valid():
            # 合并数据并加密密码
            person_data = request.session['person_basic_data']
            person_data.update(auth_form.cleaned_data)
            person_data['p_Password'] = make_password(person_data['p_Password'])
            # 创建并保存实例
            Person.objects.create(**person_data)
            # 清理临时数据
            del request.session['person_basic_data']
            return redirect('signup_success')
    else:
        auth_form = PersonAuthForm()
    return render(request, 'signup_step2.html', {'form': auth_form})

# 注册成功页视图(可选)
def signup_success(request):
    return render(request, 'signup_success.html')

3. 配置URL路由

在urls.py中添加对应路由:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('signup/step1/', views.signup_step1, name='signup_step1'),
    path('signup/step2/', views.signup_step2, name='signup_step2'),
    path('signup/success/', views.signup_success, name='signup_success'),
]

4. 调整模板文件

第一步模板signup_step1.html

<form action="{% url 'signup_step1' %}" method="post">
    {% csrf_token %}
    <label for="p_fName">First Name</label><br>
    {{ form.p_fName }}<br>
    <label for="p_lName">Last Name</label><br>
    {{ form.p_lName }}<br>
    <label for="p_SSN">SSN Code</label><br>
    {{ form.p_SSN }}<br>
    <label for="p_birthDate">Birthdate</label><br>
    {{ form.p_birthDate }}<br>
    <label for="p_phoneNum">Phone Number</label><br>
    {{ form.p_phoneNum }}<br><br>
    <button type="submit">Next Step</button>
</form>

第二步模板signup_step2.html

<form action="{% url 'signup_step2' %}" method="post">
    {% csrf_token %}
    <label for="p_Email">Email</label><br>
    {{ form.p_Email }}<br>
    <label for="p_Password">Password</label><br>
    {{ form.p_Password }}<br><br>
    <button type="submit">Complete Signup</button>
</form>

关键注意事项

  • 由于Person模型所有字段均为null=False,无法先创建部分字段的实例,必须通过session暂存数据后合并创建。
  • 密码字段使用PasswordInput组件隐藏输入内容,并通过make_password加密存储,避免明文泄露。
  • 完成注册后立即清理session中的临时数据,防止敏感信息残留。

内容的提问来源于stack exchange,提问作者mirOOxi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:54:18