如何编写自己的Django表单窗口小部件?

时间:2016-07-03 06:31:10

标签: python django django-forms django-widget

任何人都可以提供简单示例,以便我了解这是如何完成的基本习惯用法?我找不到任何有关该主题的有用文档。

为了提供更多的上下文,我想创建自己的单选按钮,这些按钮以特定的方式呈现。

我只是想找一个非常简单的例子来帮助我理解这个概念。

1 个答案:

答案 0 :(得分:1)

很难说出你的意思"一个非常简单的例子"。这是一个非常简单的例子:

from django.forms.widgets import Input

class TelInput(Input):
    input_type = 'tel'

但我认为这对你没有多大帮助。

如果您正在寻找示例,最好还是查看django source code

我认为这应该足以理解它是如何运作的:

from django.utils.encoding import force_text
from django.utils.html import format_html
from django.forms.utils import flatatt

class Widget(...):

    def __init__(self, attrs=None):
        if attrs is not None:
            self.attrs = attrs.copy()
        else:
            self.attrs = {}

    def subwidgets(self, name, value, attrs=None, choices=()):
        """
        Yields all "subwidgets" of this widget. Used only by RadioSelect to
        allow template access to individual <input type="radio"> buttons.
        Arguments are the same as for render().
        """
        yield SubWidget(self, name, value, attrs, choices)

    def render(self, name, value, attrs=None):
        """
        Returns this Widget rendered as HTML, as a Unicode string.
        The 'value' given is not guaranteed to be valid input, so subclass
        implementations should program defensively.
        """
        raise NotImplementedError('subclasses of Widget must provide a render() method')

    def build_attrs(self, extra_attrs=None, **kwargs):
        "Helper function for building an attribute dictionary."
        attrs = dict(self.attrs, **kwargs)
        if extra_attrs:
            attrs.update(extra_attrs)
        return attrs

    def value_from_datadict(self, data, files, name):
        """
        Given a dictionary of data and this widget's name, returns the value
        of this widget. Returns None if it's not provided.
        """
        return data.get(name)


class Input(Widget):
    """
    Base class for all <input> widgets (except type='checkbox' and
    type='radio', which are special).
    """
    input_type = None  # Subclasses must define this.

    def format_value(self, value):
        if self.is_localized:
            return formats.localize_input(value)
        return value

    def render(self, name, value, attrs=None):
        if value is None:
            value = ''
        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
        if value != '':
            # Only add the 'value' attribute if a value is non-empty.
            final_attrs['value'] = force_text(self.format_value(value))
        return format_html('<input{} />', flatatt(final_attrs))

大多数相关方法是render(),它将窗口小部件呈现为HTML代码,value_from_datadict()POST数据字典中提取窗口小部件的值。