Django 1.9.7
class PlaceName(models.Model):
one = ForeignKey(Place, on_delete=models.CASCADE)
...
class PlaceNameCreate(CreateView):
model = PlaceName
fields = ['one', 'name', 'since', ]
@register.filter
def disable_one(value):
"""
Disable selection of "one" field in case of one-to-many relations.
"""
value = value.replace('name="one"', 'name="one" disabled')
value = mark_safe(value)
return value
<form method="post" action="">
{% csrf_token %}
<table>
{{ form.as_table|disable_one }}
</table>
<input type="submit" value="Сохранить"/>
</form>
此PlaceName是一个从属参考书,主要是Place。从PlaceView(DetailView)我调用PlaceNameCreate,传输一个有符号值的Place,并且不希望允许用户更改它。
嗯,这不起作用。在ForeignKey的页面上有一条消息“此字段是必需的”。
如果我从模板中删除了disable_one过滤器,一切正常:成功保存模型实例。
如果我挖掘FormMixin并且在方法get_form中我可以看到
dict: {'instance': None, 'data': <QueryDict: {'since': ['2'], 'csrfmiddlewaretoken': ['6NPIva2Z7XEZzuG2xgWB3sAz0N1SPqZc'], 'name': ['2']}>, 'files': <MultiValueDict: {}>, 'prefix': None, 'initial': {}}
这意味着一个字段为空。表格无效并不奇怪。
没有过滤器:
dict: {'instance': None, 'data': <QueryDict: {'one': ['3'], 'since': ['3'], 'csrfmiddlewaretoken': ['6NPIva2Z7XEZzuG2xgWB3sAz0N1SPqZc'], 'name': ['2']}>, 'files': <MultiValueDict: {}>, 'prefix': None, 'initial': {}}
我检查了渲染的html。唯一的区别 - 正如预期的那样 - 属性“禁用”。
任何变体都是可以接受的,我使用过滤器的方式不是教条。我只是认为这是最简单的一个。
你能给我一个提示如何实现我目前的目标:向用户展示价值,而不可能选择其他变种。
稍后添加:
我按照建议尝试了readonly。不工作。这是渲染的html。
<!DOCTYPE html>
...
<select id="id_one" name="one" readonly>
<option value="">---------</option>
<option value="3" selected="selected">664011</option>
</select>
嗯,在浏览器中,用户仍然可以在两个值之间进行选择(“---------”和“664011”。
再次添加
此问题被视为重复。但事实并非如此。这是纯粹的 Django的问题。建议我作为解决方案是这样的:禁用元素,但将值保留在隐藏的输入中。然后使用JQuery。这不是我想做的事。
可能的解决方案
我刚决定剥夺用户的任何其他选择。如果没有更好的解决方案,这是可以接受的。
def get_form(self, form_class):
form = super(PlaceNameCreate, self).get_form(form_class)
one = self.initial.get('one')
choices = ((one.id, one),)
form.fields['one'].widget = forms.Select(choices=choices)
return form
答案 0 :(得分:1)
disabled
输入值未随表单一起提交。来自MDN:
<强>停用强>
此布尔属性表示表单控件不可用于交互。特别是,不会在禁用的控件上调度click事件。此外,已禁用控件的值不会随表单一起提交。
相反,您应该考虑使用readonly
:
<强>只读强>
此布尔属性表示用户无法修改控件的值。
value = value.replace('name="one"', 'name="one" readonly')
答案 1 :(得分:0)
def get_form(self, form_class):
"""
For one-to-many relationships.
Deprive user of any choice.
"""
form = super(CreateSubordinate, self).get_form(form_class)
one = self.initial.get('one')
if one:
choices = ((one.id, one),)
form.fields['one'].widget = forms.Select(choices=choices)
return form