Django:如何从URL参数设置ModelForm外键字段默认值并只读提交?
解决外键字段通过URL参数设置默认值并只读提交的问题
我来帮你搞定这个问题,核心是要让表单正确识别外键字段的参数,同时保证字段只读且能被正常提交。下面分步骤修改你的代码:
1. 修改视图(views.py):初始化表单时设置外键初始值
首先在视图里,我们要把URL传递的reference_id作为表单reference字段的初始值,同时要确保这个ID对应的Orders实例真实存在(避免无效ID导致错误):
from django.shortcuts import get_object_or_404 def add_manifest(request, reference_id): # 先获取对应的Orders实例,不存在则返回404 order = get_object_or_404(Orders, id=reference_id) if request.method == "POST": form = CreateManifestForm(request.POST) if form.is_valid(): form.save() return redirect('add_manifest', reference_id=reference_id) # 初始化表单时,将reference字段的默认值设为传入的reference_id form = CreateManifestForm(initial={'reference': reference_id}) manifests = Manifests.objects.all() context = { 'form': form, 'reference_id': reference_id, 'manifests' : manifests, 'order': order, # 可选,用于在模板显示订单的额外信息 } return render(request, 'add_manifest.html', context)
2. 修改表单(forms.py):配置外键字段的显示方式
这里提供两种方案,根据你的需求选择:
方案A:隐藏字段(用户看不到该字段)
如果不需要用户看到reference_id,直接把字段设为隐藏:
class CreateManifestForm(forms.ModelForm): class Meta: model = Manifests fields = ('reference', 'cases', 'description', 'count') widgets = { 'reference': forms.HiddenInput(), }
方案B:显示为只读文本(用户能看到但无法编辑)
如果需要用户看到reference_id但不能修改,用只读输入框:
class CreateManifestForm(forms.ModelForm): reference = forms.ModelChoiceField( queryset=Orders.objects.all(), widget=forms.TextInput(attrs={'readonly': 'readonly'}) ) class Meta: model = Manifests fields = ('reference', 'cases', 'description', 'count')
注意:不要用
disabled属性,因为浏览器不会提交被标记为disabled的字段值,而readonly只会禁止编辑,依然会提交字段值。
3. 修改模板(add_manifest.html):正确渲染表单字段
现在不用自己写独立的input了,直接使用表单渲染的字段,这样能保证字段的name属性正确,后台能接收到值:
<div class="container"> <form method="POST"> <br> <br> {% csrf_token %} <div class="column"> <label for="{{ form.reference.id_for_label }}">Reference ID: </label><br> <!-- 直接渲染表单的reference字段 --> {{ form.reference }} <!-- 如果你想显示纯文本而非输入框,可替换为下面的代码 --> <!-- {{ order.id }} <!-- 显示订单ID --> <!-- {{ form.reference.as_hidden }} <!-- 隐藏字段用于提交值 --> </div> <div class="column"> <label for="{{ form.description.id_for_label }}">Description: </label> <br> {{ form.description}} </div> <div class="column"> <label for="{{ form.cases.id_for_label }}">Cases: </label> <br> {{ form.cases }} <br> </div> <div class="column"> <label for="{{ form.count.id_for_label }}">Count: </label> <br> {{ form.count }} <br> <br> </div> <br> <br> <button type="submit" name="add_mani" style="border-color: #7395AE;">Add Line</button> </form> </div>
为什么原来的代码无法提交?
你之前自定义的<input type="text" value="{{ reference_id }}">没有设置name属性,表单提交时后台接收不到这个值;而且即使加了name,也没有和表单的reference字段关联,导致表单验证时reference字段(必填外键)缺失值,最终无法通过验证。
修改后,表单会正确初始化外键值,字段要么隐藏要么只读,提交时能传递正确的参数,验证通过后就能正常保存到数据库了。
内容的提问来源于stack exchange,提问作者GXM100
相关产品推荐
相关产品推荐

