0
点赞
收藏
分享

微信扫一扫

django框架的使用及其梳理系列七

登录注册案例会写在项目分享中

form源码-模版渲染

def render(request, template_name, context=None, content_type=None, status=None, using=None):

    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)


def render_to_string(template_name, context=None, request=None, using=None):
        template = get_template(template_name, using=using)
    return template.render(context, request)

from django.shortcuts import HttpResponse, render
from django.template.loader import get_template


def v1(request):
    template = get_template("v1.html")
    text = template.render({"text": "admin"}, request)
    print(text)

    return HttpResponse("OK")

django框架的使用及其梳理系列七_html

插件

class Widget(metaclass=MediaDefiningClass):

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

    def render(self, name, value, attrs=None, renderer=None):
        # name="user" value="admin"  attrs=None   self.attrs={'class': "c1", "id": "xx1"}
        context = self.get_context(name, value, attrs)
        
        return self._render(self.template_name, context, renderer)
    
    def get_context(self, name, value, attrs):
        return {
            "widget": {
                "name": name, # "user"
                "value": self.format_value(value), # "admin"
                "attrs": self.build_attrs(self.attrs, attrs), # {'class': "c1", "id": "xx1"}
                "template_name": self.template_name, # "django/forms/widgets/text.html"
                # "type":"text"
            },
        }

class Input(Widget):
    input_type = None  # Subclasses must define this.
    template_name = "django/forms/widgets/input.html"

    def __init__(self, attrs=None):
        if attrs is not None:
            attrs = attrs.copy()
            self.input_type = attrs.pop("type", self.input_type)
        super().__init__(attrs)


    def get_context(self, name, value, attrs):
        # {"widget":{"name":}   }
        context = super().get_context(name, value, attrs)
        context["widget"]["type"] = self.input_type
        return context
    
class TextInput(Input):
    input_type = "text"
    template_name = "django/forms/widgets/text.html"
    
    
class PasswordInput(Input):
    input_type = "password"
    template_name = "django/forms/widgets/password.html"

    def __init__(self, attrs=None, render_value=False):
        super().__init__(attrs)
        self.render_value = render_value

    def get_context(self, name, value, attrs):
        if not self.render_value:
            value = None
        return super().get_context(name, value, attrs)

class BaseForm(RenderableFormMixin):

    def __init__(
        self,
        data=None,
        files=None,
        auto_id="id_%s",
        prefix=None,
        initial=None,
        error_class=ErrorList,
        label_suffix=None,
        empty_permitted=False,
        field_order=None,
        use_required_attribute=None,
        renderer=None,
    ):
    self.order_fields(self.field_order if field_order is None else field_order)
    #渲染
    if renderer is None:
        if self.default_renderer is None:
            renderer = get_default_renderer()
            else:
                renderer = self.default_renderer
                if isinstance(self.default_renderer, type):
                    renderer = renderer()
            self.renderer = renderer
    
    #按照顺序展示
    def order_fields(self, field_order):
        if field_order is None:
            return
        fields = {}
        for key in field_order:
            try:
                fields[key] = self.fields.pop(key)
            except KeyError:  # ignore unknown fields
                pass
        fields.update(self.fields)  # add remaining fields in original order
        self.fields = fields

init&&new

class Foo(object):
    def __init__(self,name):
        self.name = name 

# 1. __new__ 去创建空对象 {}   -> 构造方法(创建对象)
# 2. __init__在对象中进行初始化 {"name":"admin"}   -> 初始化方法
obj = Foo("admin")


class Foo(object):
    def __init__(self, name):
        print("init初始化", self)
        self.name = name

    def __new__(cls, *args, **kwargs):
        obj = super().__new__(cls)
        print("new创建对象", obj)
        return obj


instance = Foo("admin")
print("得到对象", instance)

元类

默认情况下,类都是由type创建

class Info(object):
    city = "背景"

    def show(self):
        print("123")

# Info = type("Info", (object,), {"city": "背景", "show": lambda self: print(123)})

obj = Info()
print(obj.city)
obj.show()

想要由其他的东西创建类,就可以使用metaclass进行指定。

class Info(object,metaclass=其他):
    city = "背景"

    def show(self):
        print("123")

        
class MyType(type):
    pass


class Info(object, metaclass=MyType):
    city = "背景"

    def show(self):
        print("123")        

类是有type创建的,类又可以进行实例化,去创建对象。

class MyType(type):
    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)

    def __new__(cls, *args, **kwargs):
        clazz = super().__new__(cls, *args, **kwargs)
        clazz.base_declare = [11, 22, 33]
        return clazz


class Info(object, metaclass=MyType):
    city = "背景"

    def show(self):
        print("123")

print(Info.base_declare)

isinstance

判断某个对象是否是某个类或其子类创建的对象。

class Foo(object):
    pass


class Info(object):
    pass


obj1 = Foo()
obj2 = Foo()

print(isinstance(obj1, Foo))
print(isinstance(obj2, Info))

class Field(object):
    pass


class CharField(Field):
    pass


class EmailField(Field):
    pass


class ImageField(Field):
    pass


obj1 = CharField()
obj2 = EmailField()
obj3 = ImageField()

print(isinstance(obj1, Field))
print(isinstance(obj2, Field))
print(isinstance(obj3, Field))

功能:很多对象可以判断这些对象,都是Field的子类创建的对象

Form组件-定义类

class DeclarativeFieldsMetaclass(MediaDefiningClass):
    """Collect Fields declared on the base classes."""

    def __new__(mcs, name, bases, attrs):
        # Collect fields from current class and remove them from attrs.
        attrs["declared_fields"] = {
            key: attrs.pop(key)
            for key, value in list(attrs.items())
            if isinstance(value, Field)
        }

        new_class = super().__new__(mcs, name, bases, attrs)

        # Walk through the MRO.
        declared_fields = {}
        for base in reversed(new_class.__mro__):
            # Collect fields from base class.
            if hasattr(base, "declared_fields"):
                declared_fields.update(base.declared_fields)

            # Field shadowing.
            for attr, value in base.__dict__.items():
                if value is None and attr in declared_fields:
                    declared_fields.pop(attr)

        new_class.base_fields = declared_fields
        new_class.declared_fields = declared_fields

        return new_class


Form组件-创建类的对象

class BaseForm(RenderableFormMixin):
    field_order = None
    
    def __init__(self,data=None,files=None,auto_id="id_%s",prefix=None,initial=None,....,field_order=None,renderer=None):
        self.fields = copy.deepcopy(self.base_fields)
        self.order_fields(  self.field_order if field_order is None else field_order   )
        self.initial = initial or {}
        
        renderer = get_default_renderer()
        self.renderer = renderer
        
    def order_fields(self, field_order):

        if field_order is None:
            return
        fields = {}
        for key in field_order:
            try:
                fields[key] = self.fields.pop(key)
            except KeyError:  # ignore unknown fields
                pass
        fields.update(self.fields)  # add remaining fields in original order
        self.fields = fields

class Form(BaseForm, metaclass=DeclarativeFieldsMetaclass):
    pass


class LoginForm(forms.Form):
    username = forms.CharField(label="用户名", required=True, widget=forms.TextInput)
    pwd = forms.CharField(label="密码", required=True, widget=forms.PasswordInput)


form = LoginForm(initial={})

Form组件-对象.字段

设置__getitem

    def __getitem__(self, name):
        """Return a BoundField with the given name."""
        try:
             # 再包装(label="用户名", required=True, widget=forms.TextInput)
            # 之前在LoginForm中定义的 forms.CharField(label="用户名", required=True, widget=forms.TextInput) 对象
            field = self.fields[name]
        except KeyError:
            raise KeyError(
                "Key '%s' not found in '%s'. Choices are: %s."
                % (
                    name,
                    self.__class__.__name__,
                    ", ".join(sorted(self.fields)),
                )
            )
        if name not in self._bound_fields_cache:
            self._bound_fields_cache[name] = field.get_bound_field(self, name)
        return self._bound_fields_cache[name]

    
form = LoginForm(initial={})
form['username']    => 最外层的包装 BoundField(form, self, field_name)  -> 【form对象,(label="用户名", required=True, widget=forms.TextInput),“username” 】    

class BoundField:
    "A Field plus data"

    def __init__(self, form, field, name):
        self.form = form    # Form对象
        self.field = field  #  forms.CharField(label="用户名", required=True, widget=forms.TextInput)
        self.name = name    # "username"
        self.html_name = form.add_prefix(name)
        self.html_initial_name = form.add_initial_prefix(name)
        self.html_initial_id = form.add_initial_prefix(self.auto_id)
        if self.field.label is None:
            self.label = pretty_name(name)
        else:
            self.label = self.field.label
        self.help_text = field.help_text or ""

    def __str__(self):
        """Render this field as an HTML widget."""
        return self.as_widget() # <input type="text" name="username" required id="id_username">


    def as_widget(self, widget=None, attrs=None, only_initial=False):

        # 插件对象
        widget = widget or self.field.widget
        
        if self.field.localize:
            widget.is_localized = True
        attrs = attrs or {}
        attrs = self.build_widget_attrs(attrs, widget)
        if self.auto_id and "id" not in widget.attrs:
            attrs.setdefault(
                "id", self.html_initial_id if only_initial else self.auto_id
            )
        if only_initial and self.html_initial_name in self.form.data:
            # Propagate the hidden initial value.
            value = self.form._widget_data_value(
                self.field.hidden_widget(),
                self.html_initial_name,
            )
        else:
            value = self.value()

        # 字符串= 插件forms.TextInput对象.render  《input name='?' class=".."/>
        return widget.render(
            name=self.html_initial_name if only_initial else self.html_name,
            value=value,
            attrs=attrs,
            renderer=self.form.renderer,
        )

Form组件-可迭代对象

class MyForm(object):
    def __iter__(self):
        return iter([11, 22, 33, 44])


obj = MyForm()
for item in obj:
    print(item)

举报

相关推荐

0 条评论