Django函数视图实现User模型下拉选择并保存至KeyInstance
当然可行!不过你现在的实现方式有点绕,其实Django表单系统已经提供了完美的解决方案来处理这种关联模型的下拉选择,我来帮你梳理两种实现方式,优先推荐更规范的表单整合方案:
方案一:用Django表单的ModelChoiceField(推荐)
这种方式最符合Django的最佳实践,把下拉选择逻辑整合到表单里,不用手动写HTML的select标签,还能自动做合法性验证。
1. 先修改你的UpdateKeyForm
打开forms.py(如果没有就新建),把borrower字段定义为ModelChoiceField,关联User模型:
from django import forms from .models import KeyInstance, User # 确保导入正确的User模型 class UpdateKeyForm(forms.ModelForm): # 生成User模型的下拉选择框,empty_label是默认提示文本 borrower = forms.ModelChoiceField( queryset=User.objects.all(), empty_label="请选择借款人", label="借款人" ) class Meta: model = KeyInstance # 这里只包含borrower字段,如果还有其他需要的字段可以补充 fields = ['borrower']
2. 简化视图代码
你原来的names = get_list_or_404(Users)可以删掉了,因为表单已经自动获取User列表了。视图里只需要处理表单即可:
def submit_key_request(request, pk): """ View function for renewing a specific keyInstance by admin """ key_inst = get_object_or_404(KeyInstance, pk=pk) if request.method == 'POST': # 传入instance直接绑定到现有模型对象 form = UpdateKeyForm(request.POST, instance=key_inst) if form.is_valid(): # 设置其他状态字段 key_inst.is_requested = True key_inst.status = 'r' key_inst.date_requested = datetime.date.today() form.save() # 保存表单里的borrower字段到模型 return HttpResponseRedirect(reverse('all-available-keys')) else: # GET请求时初始化表单,可设置默认值或留空使用empty_label form = UpdateKeyForm(initial={'borrower': None}) return render(request, 'catalog/keyinstance_request_update.html', {'form': form, 'keyinst': key_inst})
3. 简化模板代码
模板里可以删掉手动写的select标签,直接用{{ form }}就能渲染出正确的下拉选择框:
{% extends "base_generic.html" %} {% block content %} <div class="wrapper"> <div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1> </div> <div class="square-box"> <div class="square-content"> <form action="" method="post" > {% csrf_token %} <table style="display: inline-flex"> {{ form }} <!-- 自动渲染包含borrower下拉框的表单 --> </table> <p> (Please use their login name i.e. <b>{{ user.get_username }}</b>)</p> <p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the <a href="{% url 'key-agreement'%}">terms and conditions</a></p> <p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p> <input type="submit" value="Submit" /> </form> </div> </div> </div> {% endblock %}
方案二:保留手动写的select标签(不推荐,但可实现)
如果你坚持要手动写HTML的select,那需要调整几个地方来确保能正确获取选中值:
1. 修改模板的select标签
把select的name改成borrower(和模型字段名一致),并且option的value用User的id(因为关联字段需要存储对象id):
<select name='borrower'> {% for user in names %} <option value="{{ user.id }}">{{ user.username }}</option> {% endfor %} </select>
2. 修改视图的POST处理逻辑
在表单验证后,从request.POST中获取选中的用户id,然后查询对应的User对象赋值给borrower:
if form.is_valid(): key_inst.is_requested = True key_inst.status = 'r' key_inst.date_requested = datetime.date.today() # 获取选中的用户id borrower_id = request.POST.get('borrower') # 查询对应的User对象(建议加异常处理,防止无效id导致报错) key_inst.borrower = User.objects.get(id=borrower_id) key_inst.save() return HttpResponseRedirect(reverse('all-available-keys'))
注意:这种方式需要自己处理合法性验证(比如用户提交了不存在的id会抛出异常),所以不如方案一省心。
内容的提问来源于stack exchange,提问作者UWGOOSE
相关产品推荐
相关产品推荐

