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

Django中如何设置模型实例创建确认表单并保存带外键的Solicitud?

在Django中实现带外键关联的确认表单与Solicitud保存方案

我来一步步帮你解决这个问题——从确认表单的设置,到如何通过URL传递的PK关联并保存Solicitud模型,都会给你讲清楚。

首先先明确一下我假设的模型关系(如果和你的实际情况略有出入,你可以调整字段名或关联类型):

# models.py
from django.db import models

class Candidato(models.Model):
    nombre = models.CharField(max_length=100)
    email = models.EmailField(unique=True)

class InfoPersonal(models.Model):
    candidato = models.OneToOneField(Candidato, on_delete=models.CASCADE)
    direccion = models.CharField(max_length=200)
    telefono = models.CharField(max_length=20)

class InfoAcademica(models.Model):
    candidato = models.OneToOneField(Candidato, on_delete=models.CASCADE)
    titulo = models.CharField(max_length=100)
    institucion = models.CharField(max_length=150)

class Solicitud(models.Model):
    candidato = models.ForeignKey(Candidato, on_delete=models.CASCADE)
    info_personal = models.ForeignKey(InfoPersonal, on_delete=models.CASCADE)
    info_academica = models.ForeignKey(InfoAcademica, on_delete=models.CASCADE)
    fecha_creacion = models.DateTimeField(auto_now_add=True)
    estado = models.CharField(max_length=20, default="pendiente")

步骤1:配置URL,传递所需PK参数

首先要在URL里定义好接收三个模型PK的路由,这样才能从前端把关联信息传到后端:

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

urlpatterns = [
    # 你已有的创建Candidato、InfoPersonal、InfoAcademica的URL
    # ...
    # 确认表单的URL,接收三个PK参数
    path('confirmar-solicitud/<int:candidato_pk>/<int:info_personal_pk>/<int:info_academica_pk>/', 
         views.confirmar_solicitud, 
         name='confirmar_solicitud'),
    path('solicitud-exitosa/', views.solicitud_exitosa, name='solicitud_exitosa'),
]

步骤2:创建确认表单

确认表单的核心是展示已填写的信息,不需要用户修改,只需要一个确认提交按钮。你可以用两种方式实现:

方式1:极简空表单(推荐)

这种方式最直接,只用来触发POST提交:

# forms.py
from django import forms

class ConfirmacionSolicitudForm(forms.Form):
    # 空表单,仅作为提交载体
    pass

方式2:带只读字段的ModelForm(更规范)

如果想在表单里展示关联的模型信息(但禁止修改),可以用这种:

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

class ConfirmacionSolicitudForm(forms.ModelForm):
    class Meta:
        model = Solicitud
        fields = ['candidato', 'info_personal', 'info_academica']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 把所有字段设为只读状态
        for field in self.fields.values():
            field.disabled = True

步骤3:实现确认视图逻辑

这个视图要完成三个核心工作:获取并验证关联实例、渲染确认页面、处理POST请求创建Solicitud。

# views.py
from django.shortcuts import get_object_or_404, render, redirect
from .models import Candidato, InfoPersonal, InfoAcademica, Solicitud
from .forms import ConfirmacionSolicitudForm

def confirmar_solicitud(request, candidato_pk, info_personal_pk, info_academica_pk):
    # 1. 通过PK获取对应模型实例,不存在则返回404页面
    candidato = get_object_or_404(Candidato, pk=candidato_pk)
    info_personal = get_object_or_404(InfoPersonal, pk=info_personal_pk)
    info_academica = get_object_or_404(InfoAcademica, pk=info_academica_pk)

    # 2. 关键验证:确保InfoPersonal和InfoAcademica属于当前Candidato,防止恶意篡改URL参数
    if info_personal.candidato != candidato or info_academica.candidato != candidato:
        return render(request, 'error.html', {"mensaje": "Los datos no pertenecen al mismo candidato"})

    if request.method == 'POST':
        # 3. 处理确认提交:创建Solicitud实例并关联外键
        Solicitud.objects.create(
            candidato=candidato,
            info_personal=info_personal,
            info_academica=info_academica
            # 如果有其他必填字段,比如estado,这里可以一起设置
        )
        # 提交后重定向到成功页面,避免用户刷新重复提交
        return redirect('solicitud_exitosa')

    # GET请求时,渲染确认页面
    # 如果用方式2的ModelForm,就传入initial值:
    # form = ConfirmacionSolicitudForm(initial={
    #     'candidato': candidato,
    #     'info_personal': info_personal,
    #     'info_academica': info_academica
    # })
    form = ConfirmacionSolicitudForm()
    context = {
        'candidato': candidato,
        'info_personal': info_personal,
        'info_academica': info_academica,
        'form': form
    }
    return render(request, 'confirmar_solicitud.html', context)

def solicitud_exitosa(request):
    return render(request, 'solicitud_exitosa.html')

步骤4:编写确认页面模板

在模板里展示所有已填写的信息,然后放一个确认提交按钮:

<!-- templates/confirmar_solicitud.html -->
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Confirmar Solicitud</title>
</head>
<body>
    <h1>Revisa y Confirma tus Datos</h1>

    <h2>Datos del Candidato</h2>
    <ul>
        <li>Nombre: {{ candidato.nombre }}</li>
        <li>Email: {{ candidato.email }}</li>
    </ul>

    <h2>Información Personal</h2>
    <ul>
        <li>Dirección: {{ info_personal.direccion }}</li>
        <li>Teléfono: {{ info_personal.telefono }}</li>
    </ul>

    <h2>Información Académica</h2>
    <ul>
        <li>Título: {{ info_academica.titulo }}</li>
        <li>Institución: {{ info_academica.institucion }}</li>
    </ul>

    <p>¿Todos los datos son correctos? Haz clic en confirmar para crear tu solicitud.</p>

    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Confirmar y Crear Solicitud</button>
    </form>
</body>
</html>

额外优化:自动跳转到确认页面

在你创建InfoAcademica的视图里,创建完成后自动跳转到确认页面,不需要用户手动输入URL:

# views.py 中创建InfoAcademica的视图示例
def crear_info_academica(request, candidato_pk):
    candidato = get_object_or_404(Candidato, pk=candidato_pk)
    if request.method == 'POST':
        form = InfoAcademicaForm(request.POST)
        if form.is_valid():
            info_academica = form.save(commit=False)
            info_academica.candidato = candidato
            info_academica.save()
            # 获取当前候选人的InfoPersonal实例
            info_personal = InfoPersonal.objects.get(candidato=candidato)
            # 自动跳转到确认页面,传递三个PK参数
            return redirect('confirmar_solicitud', 
                           candidato_pk=candidato.pk,
                           info_personal_pk=info_personal.pk,
                           info_academica_pk=info_academica.pk)
    # ... 其他GET请求逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:45:51