Django多表单对应多模型的外键关联保存与展示问题
解决Django双表单模型外键关联问题
看起来你已经离解决问题很近了!核心问题是你保存两个模型实例后,没有建立它们之间的外键关联,另外还有几个细节需要调整,让我们一步步来修复:
1. 先修复模型中的缺失字段(重要!)
我注意到你在视图里给post_1.author和post_2.author赋值了当前用户,但你的两个模型里都没有author字段,这会导致保存时报错。先给两个模型添加用户外键:
# models.py from django.contrib.auth.models import User class Url_activity(models.Model): url_de_la_actividad = models.URLField() nombre_url = models.CharField(max_length=10, null=True) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, null=True) lastModification = models.DateTimeField(auto_now_add=False, auto_now=True, null=True) # 添加author字段 author = models.ForeignKey(User, on_delete=models.CASCADE) def __str__(self): # 建议用__str__替代__unicode__(Python3兼容) return self.url_de_la_actividad class ActivityProposed(models.Model): nombre_actividad = models.CharField(max_length=50) detalle_de_la_actividad = models.TextField() metodologia = models.CharField(max_length=50) foreign_url = models.ForeignKey(Url_activity, on_delete=models.CASCADE, null=True, blank=True) nombre_de_la_norma = models.CharField(max_length=50) nombre_de_la_competencia = models.CharField(max_length=100) nombre_del_curso = models.CharField(max_length=50) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False, null=True) lastModification = models.DateTimeField(auto_now_add=False, auto_now=True, null=True) foreing_activity = models.ForeignKey(Activity, on_delete=models.CASCADE, null=True, blank=True) # 添加author字段 author = models.ForeignKey(User, on_delete=models.CASCADE) def __str__(self): return self.nombre_actividad
2. 调整视图中的保存逻辑,建立外键关联
因为ActivityProposed的foreign_url是指向Url_activity的外键,所以我们需要先保存Url_activity实例,再把它赋值给ActivityProposed的外键字段,最后保存ActivityProposed:
# views.py def proposeActivity(request): if request.method == "POST": form_1 = ActivityProposedForm(request.POST, prefix="form_1") form_2 = ActivityUrl_activity(request.POST, prefix="form_2") if form_1.is_valid() and form_2.is_valid(): # 先处理并保存Url_activity实例 post_2 = form_2.save(commit=False) post_2.author = request.user post_2.save() # 必须先保存,才能生成主键用于关联 # 处理ActivityProposed,关联刚保存的Url_activity post_1 = form_1.save(commit=False) post_1.author = request.user post_1.foreign_url = post_2 # 这里建立外键关联! post_1.save() return redirect('proposedActivities') else: form_1 = ActivityProposedForm(prefix="form_1") form_2 = ActivityUrl_activity(prefix="form_2") return render(request, 'registerActivity.html', {'form_1': form_1, 'form_2': form_2})
3. 单个HTML表单呈现所有字段
你已经给表单加了prefix,所以只需要在模板里把两个表单的字段放在同一个<form>标签内即可,不需要分开的表单:
<!-- registerActivity.html --> <form method="POST"> {% csrf_token %} <!-- 渲染第一个表单的字段 --> <h3>基本活动信息</h3> {{ form_1.as_p }} <!-- 渲染第二个表单的字段 --> <h3>活动URL信息</h3> {{ form_2.as_p }} <button type="submit">提交活动</button> </form>
4. 后续数据展示(单个模板呈现关联数据)
当你需要展示已提交的活动数据时,只需要从ActivityProposed实例出发,通过外键反向获取关联的Url_activity数据即可:
<!-- 示例:展示单个活动详情的模板 --> <h2>{{ activity.nombre_actividad }}</h2> <p>{{ activity.detalle_de_la_actividad }}</p> <!-- 访问关联的URL信息 --> <p>活动链接:<a href="{{ activity.foreign_url.url_de_la_actividad }}">{{ activity.foreign_url.nombre_url }}</a></p>
这样调整后,两个模型的外键关联就能正常生效,同时用户输入和数据展示都能通过单个HTML表单/模板完成。
内容的提问来源于stack exchange,提问作者Oscar Acevedo Osses
相关产品推荐
相关产品推荐

