首页 文章

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

提问于
浏览
1

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 . 唯一的区别 - 正如预期的那样 - 是“禁用”属性 .

任何变体都是可以接受的,我使用过滤器的方式不是教条 . 我只是觉得这是最简单的一个 .

你能否给我一个提示如何实现我目前的目标:向用户展示 Value ,而选择其他变种是不可能的 .

Added later:

我按照建议尝试了readonly . 不工作 . 这是渲染的html .

<!DOCTYPE html>
...
<select id="id_one" name="one" readonly>
<option value="">---------</option>
<option value="3" selected="selected">664011</option>
</select>

那么,在浏览器中,用户仍然可以在两个值之间进行选择(“---------”和“664011” .

Added again

这个问题被认为是重复的 . 但事实并非如此 . 这是一个纯粹的Django问题 . 建议我作为解决方案是这样的:禁用元素,但将值保留在隐藏的输入中 . 然后使用JQuery . 这不是我想做的 .

Possible solution

我刚决定剥夺用户任何其他选择 . 如果没有更好的解决方案,这是可以接受的 .

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

    disabled 输入值未随表单一起提交 . 从MDN

    disabled此布尔属性表示表单控件不可用于交互 . 特别是,不会在禁用的控件上调度click事件 . 此外,表单不会提交禁用控件的值 .

    相反,您应该考虑使用 readonly

    readonly此布尔属性表示用户无法修改控件的值 .

    value = value.replace('name="one"', 'name="one" readonly')
    
  • 1
    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
    

相关问题