基于wtforms源码实现自定义form组件

from flask import Flask,Markup,render_template,request,redirect
from wtforms.form import  Form

from wtforms.fields import core
from wtforms import widgets

#插件
class Widget(object):
    pass

class TextInput():
    def __call__(self, *args, **kwargs):
        return "<input type=‘text‘ name=‘name‘/>"

class TextErea():
    def __call__(self, *args, **kwargs):
        return ‘<textarea name="email"> </textarea>‘
#字段
class Field():

    def __str__(self):
        return Markup(self.widget())

class StringField(Field):
    widget=TextInput()

    def validate(self,data):
        if data:
            return True

class EmailField(Field):
    widget=TextErea()

    def validate(self,data):
        reg = ".*@.*"
        import re
        if re.match(reg,data):
            return True
#Form
class BaseForm(object):
    def __init__(self,*args,**kwargs):
        _fields={}
        for name,field in self.__class__.__dict__.items():
            if isinstance(field,Field):
                _fields[name]=field

        self._fields=_fields
        self.data={}

    def validate(self,form_data):
        flag=True
        for name,field in self._fields.items():
            input_val=form_data.get(name,‘‘)
            result=field.validate(input_val)
            if not result:
                flag=False
            else:
                self.data[name]=input_val
        return flag

class LoginForm(BaseForm):
    name=StringField()
    email=EmailField()

app=Flask(__name__)

@app.route(‘/login‘,methods=[‘GET‘,‘POST‘])
def login():
    if request.method==‘GET‘:
        form=LoginForm()
        return  render_template(‘login.html‘,form=form)
    else:
        form=LoginForm()
        if form.validate(request.form):
            print(‘login success‘)
            return ‘hello‘
        return redirect(‘/login‘)

if __name__ == ‘__main__‘:
    app.run()

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
<form  method="post">
   {{ form.name }}
    {{ form.email }}
    <input type="submit">
  </form>
</body>
</html>

根据源码可以看出,实际上请求的流程可以分为三个大类:Form,插件Widget,,字段Field,用到的更多是面向对象的知识

原文地址:https://www.cnblogs.com/ctztake/p/8260525.html

时间: 2024-11-06 03:51:20

基于wtforms源码实现自定义form组件的相关文章

Flask之wtforms源码分析

一.wtforms源码流程 1.实例化流程分析 1 # 源码流程 2 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._wtforms_meta中 3 2. 执行构造方法 4 5 a. 循环cls._unbound_fields中的字段,并执行字段的bind方法,然后将返回值添加到 self._fields[name] 中. 6 即: 7 _fields = { 8 name: wtforms.fields.

Flask 【第十篇】自定义Form组件

一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._wtforms_meta中 2. 执行构造方法 a. 循环cls._unbound_fields中的字段,并执行字段的bind方法,然后将返回值添加到 self._fields[name] 中. 即: _fields = { name: wtforms.fields.core.StringField

Flask系列(十)自定义Form组件

一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._wtforms_meta中 2. 执行构造方法 a. 循环cls._unbound_fields中的字段,并执行字段的bind方法,然后将返回值添加到 self._fields[name] 中. 即: _fields = { name: wtforms.fields.core.StringField

自定义form组件

一.wtforms源码流程 1.实例化流程分析 1 # 源码流程 2 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._wtforms_meta中 3 2. 执行构造方法 4 5 a. 循环cls._unbound_fields中的字段,并执行字段的bind方法,然后将返回值添加到 self._fields[name] 中. 6 即: 7 _fields = { 8 name: wtforms.fields.

Flask学习【第10篇】:自定义Form组件

wtforms源码流程 实例化流程分析 1 # 源码流程 2 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._wtforms_meta中 3 2. 执行构造方法 4 5 a. 循环cls._unbound_fields中的字段,并执行字段的bind方法,然后将返回值添加到 self._fields[name] 中. 6 即: 7 _fields = { 8 name: wtforms.fields.core

zabbix源码安装,自定义监控205的用户数,有触发器但没有邮件报警

zabbix源码安装,自定义监控205的用户数,有触发器但没有邮件报警 监控端配置:(192.168.4.5) 1基础环境:(实验环境可以关闭防火墙,但生产环境不能关闭,否则不安全,要设置相应规则) [[email protected]桌面]# /etc/init.d/iptables stop [[email protected]桌面]# setenforce 0 2搭建lamp平台,(它运行在lamp平台上) [[email protected]桌面]# yum -y install htt

基于LinkedBlockingQueue源码自我实现线程安全队列

LinkedBlockingQueue是一个阻塞的.线程安全的.由链表实现的双向队列,和ArrayBlockingQueue一样,是最普通也是最常用的阻塞队列.现基于LinkedBlockingQueue源码自我实现一个单向的.简化版的LinkedBlockingQueue. package com.lzq.newInterview; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Re

asp.net core源码飘香:Logging组件(转)

简介: 作为基础组件,日志组件被其他组件和中间件所使用,它提供了一个统一的编程模型,即不需要知道日志最终记录到哪里去,只需要调用它即可. 使用方法很简单,通过依赖注入ILogFactory(CreateLogger方法)或ILogger<T>对象,获取一个ILogger对象,然后通过ILogger的各种扩展方法(都是调用Log方法)记录不同级别的日志. 源码剖析: 总结: 日志组件其实就是工厂模式的应用,但进行了改进,LoggerFactory每次都返回一个Logger对象,而Logger对象

LambdaMART简介——基于Ranklib源码(一 lambda计算)

学习Machine Learning,阅读文献,看各种数学公式的推导,其实是一件很枯燥的事情.有的时候即使理解了数学推导过程,也仍然会一知半解,离自己写程序实现,似乎还有一道鸿沟.所幸的是,现在很多主流的Machine Learning方法,网上都有open source的实现,进一步的阅读这些源码,多做一些实验,有助于深入的理解方法. Ranklib就是一套优秀的Learning to Rank领域的开源实现,其主页在:http://people.cs.umass.edu/~vdang/ran