Django:从模板链接传递PK到外键表单和视图,解决表单不显示问题
Django:从模板链接传递PK到外键表单和视图,解决表单不显示问题
嘿,我仔细扒了你的代码,发现俩核心问题:一是表单压根没显示出来,二是不知道怎么把点击对象的PK传给外键表单,让提交的数据自动绑定到这个对象。咱们一步步来搞定:
首先解决表单不显示的问题
看你的book视图,你先把form_2塞进了context,但后面直接重新赋值context = {'book': book},这直接把表单给覆盖没了!模板自然拿不到form_2,显示个啥嘛。
修复后的视图代码应该是这样:
def book(request, pk): # 先拿到对应的ArkiObject_1对象 book = get_object_or_404(ArkiObject_1, pk=pk) context = {'book': book} # 处理表单提交逻辑 if request.method == 'POST': form_2 = Form_GPR(request.POST) if form_2.is_valid(): # 外键关联的逻辑后面说,先保证表单能正常提交 form_2.save() return redirect("book-detail", pk=pk) # 提交完返回当前详情页 else: # GET请求时初始化空表单 form_2 = Form_GPR() # 把表单加入context,别再覆盖了! context['form_2'] = form_2 return render(request, 'bookdetail.html', context)
这样改完,模板里就能拿到表单了,自然就能显示出来。
然后搞定PK传递,让外键自动关联当前对象
你想要的是:点击哪个对象的链接,表单提交的数据就属于哪个对象,不用用户手动选外键。有两种靠谱的方法:
方法一:隐藏外键字段,视图手动绑定
先修改你的Form_GPR,把外键字段排除掉,不让用户看到:
class Form_GPR(forms.ModelForm): class Meta: model = ArkiGpr # 排除外键name,只显示需要用户填写的字段 exclude = ['name'] # 也可以直接指定要显示的字段:fields = ['work', 'peoples']
然后在视图的表单保存步骤,手动把外键绑定到当前对象:
if form_2.is_valid(): # 先创建实例但不保存到数据库 gpr_instance = form_2.save(commit=False) # 把当前的ArkiObject_1对象绑定到外键 gpr_instance.name = book # 再保存到数据库 gpr_instance.save() return redirect("book-detail", pk=pk)
方法二:初始化表单时设外键默认值,同时隐藏字段
如果你想保留外键字段但不让用户修改,可以把它设为隐藏输入框:
class Form_GPR(forms.ModelForm): class Meta: model = ArkiGpr fields = ['work', 'peoples', 'name'] # 把name字段改成隐藏输入框 name = forms.ModelChoiceField( queryset=ArkiObject_1.objects.all(), widget=forms.HiddenInput() )
然后在视图初始化表单时,直接把当前对象设为默认值:
# GET请求初始化表单时,给name字段设初始值 form_2 = Form_GPR(initial={'name': book})
这样表单提交时,外键会自动绑定到当前对象,用户完全看不到这个字段。
最后在模板里正确渲染表单
记得在bookdetail.html里加上表单代码,还要加{% csrf_token %},不然Django会拒绝提交:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{ book.nameobject }} - 详情页</title> </head> <body> <h1>{{ book.nameobject }}</h1> <p>Городской округ: {{ book.city }}</p> <p>Тип объекта: {{ book.typeobject }}</p> <h3>Добавить мероприятие</h3> <form method="POST"> {% csrf_token %} {{ form_2.as_p }} <button type="submit">Сохранить</button> </form> </body> </html>
收尾检查
你的URL配置和模板里的链接{% url 'book-detail' book.pk %}都是对的,PK已经能正确传递到视图里。现在按上面的步骤改完,点击链接进入详情页后,表单会正常显示,提交的数据也会自动关联到你点击的那个对象啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

