登录注册案例会写在项目分享中
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")
插件
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):
= name
# 1. __new__ 去创建空对象 {} -> 构造方法(创建对象)
# 2. __init__在对象中进行初始化 {"name":"admin"} -> 初始化方法
obj = Foo("admin")
class Foo(object):
def __init__(self, name):
print("init初始化", self)
= 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)
= 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)