Django视图函数如何返回两个字典?返回infos和data失败求助
在Django视图中返回多组上下文数据的正确姿势
嘿,我看你在Django的views.py里返回infos和data这两组数据时碰到了问题,咱们来拆解下问题出在哪,以及怎么解决~
先说说你尝试的两种写法为啥不行
第一种写法
return render(request, 'index.html', {'infos':infos}, data)
Django的render函数只接受单个上下文字典作为第三个参数,你传了两个字典参数,这不符合函数定义,自然会报错。第二种写法
return render(request, 'index.html', {'infos':infos, 'data':data})
这种写法本身的思路是对的,但你的代码里data变量存在未初始化的问题:在GET请求的分支里,data完全没有被定义,当请求是GET时,走到return语句就会抛出NameError,这才是导致你觉得“无效”的核心原因。
修复后的完整代码
我帮你调整了代码,解决了data未定义的问题,同时正确合并了infos和data的内容:
def contact(request): infos = Info.objects.all() # 关键:先初始化data字典,确保所有代码路径下都有这个变量 data = {} if request.method == "POST": form = ContactForm(request.POST) if form.is_valid(): messages.success(request, 'Success') admin_address = "mail" responder_address ="responder@site.pl" client_address = request.POST['email'] message_for_admin = """ name: %s; E-mail: %s; Subject: %s; Text: %s; """ % ( request.POST['name'], request.POST['email'], request.POST['subject'], request.POST['message'] ) message_for_client = """ text """ try: send_mail(request.POST['subject'], message_for_admin, responder_address, [admin_address,]) # send_mail(request.POST['subject'], responder_address, message_for_client, [client_address,]) except BadHeaderError: print('wrong subject') data['form'] = form data['info'] = 'thanks for message' else: data['form'] = ContactForm() else: # GET请求时也要给data添加表单,避免模板渲染出错 data['form'] = ContactForm() # 合并infos和data到同一个上下文字典里 context = { 'infos': infos, **data # 用字典解包语法把data的键值对合并进来 } return render(request, 'index.html', context)
核心要点说明
- 变量初始化:一定要在函数开头就初始化
data = {},不管请求是GET还是POST,都能保证data变量存在,不会触发未定义错误。 - 上下文合并:
render只接受一个上下文字典,所以要把所有需要传给模板的变量(比如infos、form、info)都放到同一个字典里。用**data可以简洁地把data里的所有键值对合并到context中,也可以手动写'form': data['form'], 'info': data.get('info'),不过解包语法更高效。 - GET请求处理:别忘了在GET请求分支里给
data['form']赋值,不然模板里渲染表单的时候会找不到变量。
针对你的两个问题的明确回答
如何在views.py中返回两个字典?
不需要返回两个字典,而是把这两个字典的内容合并成一个单一的上下文字典,再传给render函数。比如用merged_dict = {**dict_a, **dict_b}的方式合并,或者手动把键值对逐个添加进去。如何在views.py中返回infos和data?
像上面的代码那样,先确保data在所有代码路径下都被定义,然后把infos和data的内容合并到同一个上下文字典中,最后将这个字典作为第三个参数传给render即可。
内容的提问来源于stack exchange,提问作者pkucinski
相关产品推荐
相关产品推荐

