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
相关产品推荐
相关产品推荐

