向呈现的html添加了禁用属性,现在表单无效

时间:2016-07-02 19:20:13

标签: django

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

2 个答案:

答案 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