Flask框架

news2025/1/12 1:53:55

Flask

  • 一 前言
  • 二 快速使用
  • 三 内置配置变量
  • 四 配置文件的写法
  • 五 路由
  • 六 cbv写法
    • 6.1 快速使用
    • 6.2 cbv加装饰器
    • 6.3 as_view的执行流程
    • 6.4 as_view的name参数
    • 6.5 继承View写cbv
  • 七 模板语法
    • 7.1 渲染变量
    • 7.2 变量的循环
    • 7.3 逻辑判断

一 前言

Flask是一个基于Python开发并且依赖jinja2模板(模板语言)和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。

“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。

默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。

Flask官方文档: https://dormousehole.readthedocs.io/en/latest/

二 快速使用

安装

pip install Flask

使用

from flask import Flask  # 导入Flask类

# 实例化产生Flask对象 有了__name__ Flask才知道在哪里找到模板和静态文件
app = Flask(__name__)  

# 使用route装饰器来声明路由匹配成功执行的视图函数
@app.route('/')
def hello_word():
    return 'Hello World!'


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

三 内置配置变量

在Flask类实例化app对象时将默认配置赋值给了app.config

Flask/_init_

#: The configuration dictionary as :class:`Config`.  This behaves
#: exactly like a regular dictionary but supports additional methods
#: to load a config from files.
self.config = self.make_config(instance_relative_config))

flask/app.py

default_config = ImmutableDict(
    {
        "ENV": None,
        "DEBUG": None,
        "TESTING": False,
        "PROPAGATE_EXCEPTIONS": None,
        "PRESERVE_CONTEXT_ON_EXCEPTION": None,
        "SECRET_KEY": None,
        "PERMANENT_SESSION_LIFETIME": timedelta(days=31),
        "USE_X_SENDFILE": False,
        "SERVER_NAME": None,
        "APPLICATION_ROOT": "/",
        "SESSION_COOKIE_NAME": "session",
        "SESSION_COOKIE_DOMAIN": None,
        "SESSION_COOKIE_PATH": None,
        "SESSION_COOKIE_HTTPONLY": True,
        "SESSION_COOKIE_SECURE": False,
        "SESSION_COOKIE_SAMESITE": None,
        "SESSION_REFRESH_EACH_REQUEST": True,
        "MAX_CONTENT_LENGTH": None,
        "SEND_FILE_MAX_AGE_DEFAULT": None,
        "TRAP_BAD_REQUEST_ERRORS": None,
        "TRAP_HTTP_EXCEPTIONS": False,
        "EXPLAIN_TEMPLATE_LOADING": False,
        "PREFERRED_URL_SCHEME": "http",
        "JSON_AS_ASCII": True,
        "JSON_SORT_KEYS": True,
        "JSONIFY_PRETTYPRINT_REGULAR": False,
        "JSONIFY_MIMETYPE": "application/json",
        "TEMPLATES_AUTO_RELOAD": None,
        "MAX_COOKIE_SIZE": 4093,
    }

ENV:应用运行于什么环境。 Flask 和 扩展可以根据环境不同而行为不同,如打开或 关闭调试模式。 env 属性映射了这个配置键。本变量由 FLASK_ENV 环境变量设置。如果本变量是在代码中设置的话,可能出 现意外。在生产环境中不要使用 development 。

DEBUG:是否开启调试模式。使用 flask run 启动开发服务器时,遇到未能处理的 异常时会显示一个交互调试器,并且当代码变动后服务器会重启。 debug 属性映射了这个配置键。当 ENV 是 ‘development’ 时,本变量会启用,并且会被 FLASK_DEBUG 环境变量 重载。如果本变量是在代码中设置的话,可能会出现意外。在生产环境中不要开启调试模式。

TESTING:开启测试模式。异常会被广播而不是被应用的错误处理器处理。扩展可能也会为 了测试方便而改变它们的行为。你应当在自己的调试中开启本变量。

PROPAGATE_EXCEPTIONS:异常会重新引发而不是被应用的错误处理器处理。在没有设置本变量的情况下, 当 TESTING 或 DEBUG 开启时,本变量隐式地为真。

PRESERVE_CONTEXT_ON_EXCEPTION:当异常发生时,不要弹出请求情境。在没有设置该变量的情况下,如果 DEBUG 为真,则本变量为真。这样允许调试器错误请求数据。本变量通常不 需要直接设置。

SECRET_KEY:密钥用于会话 cookie 的安全签名,并可用于应用或者扩展的其他安全需求。 密钥应当是一个长的随机的 bytes 或者 str 。例如,复制下面的 输出到你的配置中:

import secrets

print(secrets.token_hex())
# cd607def747f7d3f0d15219cf3e89b6e5be13aafe91d163a676ed6d54bb09ecd

PERMANENT_SESSION_LIFETIME:如果 session.permanent 为真, cookie 的有效期为本变量设置的数字, 单位为秒。本变量可能是一个 datetime.timedelta 或者一个 int 。

USE_X_SENDFILE:当使用 Flask 提供文件服务时,设置 X-Sendfile 头部。有些网络服务器, 如 Apache ,识别这种头部,以利于更有效地提供数据服务。本变量只有使用这 种服务器时才有效。

SERVER_NAME:通知应用其所绑定的主机和端口。子域路由匹配需要本变量。

APPLICATION_ROOT:通知应用应用的根路径是什么。这个变量用于生成请求环境之外的 URL。

SESSION_COOKIE_NAME:会话 cookie 的名称。假如已存在同名 cookie ,本变量可改变。

SESSION_COOKIE_DOMAIN:认可会话 cookie 的域的匹配规则。如果本变量没有设置,那么 cookie 会被 SERVER_NAME 的所有子域认可。如果本变量设置为 False ,那么 cookie 域不会被设置。

SESSION_COOKIE_PATH:认可会话 cookie 的路径。如果没有设置本变量,那么路径为 APPLICATION_ROOT ,如果 APPLICATION_ROOT 也没有设置,那么会是 / 。

SESSION_COOKIE_HTTPONLY:为了安全,浏览器不会允许 JavaScript 操作标记为“ HTTP only ”的 cookie 。

SESSION_COOKIE_SECURE:如果 cookie 标记为“ secure ”,那么浏览器只会使用基于 HTTPS 的请求发 送 cookie 。应用必须使用 HTTPS 服务来启用本变量。

SESSION_COOKIE_SAMESITE:限制来自外部站点的请求如何发送 cookie 。可以被设置为 ‘Lax’ (推荐) 或者 ‘Strict’ 。

SESSION_REFRESH_EACH_REQUEST:当 session.permanent 为真时,控制是否每个响应都发送 cookie 。每次 都发送 cookie (缺省情况)可以有效地防止会话过期,但是会使用更多的带宽。 会持续会话不受影响。

MAX_CONTENT_LENGTH:在进来的请求数据中读取的最大字节数。如果本变量没有配置,并且请求没有指 定 CONTENT_LENGTH ,那么为了安全原因,不会读任何数据。

SEND_FILE_MAX_AGE_DEFAULT:当提供文件服务时,设置缓存控制最长存活期,以秒为单位。可以是一个 datetime.timedelta 或者一个 int 。在一个应用或者蓝图上 使用 get_send_file_max_age() 可以基于单个文件重载 本变量。

TRAP_BAD_REQUEST_ERRORS:尝试操作一个请求字典中不存在的键,如 args 和 form ,会返回一个 400 Bad Request error 页面。开启本变量,可以把这种错误作为一个未处理的 异常处理,这样就可以使用交互调试器了。本变量是一个特殊版本的 TRAP_HTTP_EXCEPTIONS 。如果没有设置,本变量会在调试模式下开启。

TRAP_HTTP_EXCEPTIONS:如果没有处理 HTTPException 类型异常的处理器,重新引发该异常用于被 交互调试器处理,而不是作为一个简单的错误响应来返回。

EXPLAIN_TEMPLATE_LOADING:记录模板文件如何载入的调试信息。使用本变量有助于查找为什么模板没有载入 或者载入了错误的模板的原因。

PREFERRED_URL_SCHEME:当不在请求情境内时使用些预案生成外部 URL 。

JSON_AS_ASCII:把对象序列化为 ASCII-encoded JSON 。如果禁用,那么 jsonify 返回 的 JSON 会包含 Unicode 字符。这样的话,在把 JSON 渲染到 JavaScript 时会有安全隐患。因此,通常应当开启这个变量。

JSON_SORT_KEYS:按字母排序 JSON 对象的键。这对于缓存是有用的,因为不管 Python 的哈希种 子是什么都能够保证数据以相同的方式序列化。为了以缓存为代价的性能提高可 以禁用它,虽然不推荐这样做。

JSONIFY_PRETTYPRINT_REGULAR:jsonify 响应会输出新行、空格和缩进以便于阅读。在调试模式下总是启用 的。

JSONIFY_MIMETYPE:jsonify 响应的媒体类型。

TEMPLATES_AUTO_RELOAD:当模板改变时重载它们。如果没有配置,在调试模式下会启用。

MAX_COOKIE_SIZE:当 cookie 头部大于本变量配置的字节数时发出警告。缺省值为 4093 。 更大的 cookie 会被浏览器悄悄地忽略。本变量设置为 0 时关闭警告。

四 配置文件的写法

1. 直接通过app对象添加配置

app = Flask(__name__)
print(app.config)
app.debug = True
app.secret_key = secrets.token_hex()
print(app.config)

在这里插入图片描述
2. 通过app.config配置

app = Flask(__name__)
print(app.config)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = secrets.token_hex()
print(app.config)

3. 通过配置文件

settings.py

import secrets

DEBUG = True
SECRET_KEY = secrets.token_hex()

app.py

app = Flask(__name__)
app.config.from_pyfile('settings.py')
print(app.config)

4. 通过类配置

setting_class.py

# 开发配置
class DevelopmentConfig:
    DEBUG = True
    SERVER_NAME = 'localhost'

# 上线配置
class ProductionConfig:
    DEBUG = False
    SERVER_NAME = '192.168.1.11'

app.py

app.config.from_object('setting_class.ProductionConfig')
print(app.config)

5. 其他

app.config.from_envvar("环境变量名称")

app.config.from_json("json文件名称")

五 路由

现代 web 应用都使用有意义的 URL ,这样有助于用户记忆,网页会更得到用户的青睐, 提高回头率。

使用 route() 装饰器来把函数绑定到 URL:

@app.route('/')
def index():
    return 'index page!'


@app.route('/login')
def login():
    return 'login page!'

但是能做的不仅仅是这些!您可以动态变化 URL 的某些部分, 还可以为一个函数指定多个规则。

通过把 URL 的一部分标记为<variable_name> 就可以在 URL 中添加变量。标记的 部分会作为关键字参数传递给函数。通过使用 <converter:variable_name> ,可以 选择性的加上一个转换器,为变量指定规则。请看下面的例子:

from flask import Flask

app = Flask(__name__)


@app.route('/user/<username>')
def show_user_profile(username):
    # 显示该用户
    return f'User {username}'


@app.route('/post/<int:post_id>')
def show_post(post_id):
    # 显示id是一个数字
    return f'Post {post_id}'


@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # 显示path后的子路径
    return f'Subpath {subpath}'


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

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
route参数

- methods:列表,规定请求的方式,如果列表中没有,该请求方式不被支持。
- endpoint:路由别名,如果不写,会以被装饰的函数名作为别名。

转换器类型:

类型描述
string接受任何不包含斜杠的字符串
int接受任意正整数
float接受正浮点数
path类似于string,但可以包含斜杠
uuid接受UUID字符串

路由源码

@app.route('/')
def hello_word():
    return 'Hello World!'

首先执行app对象(Flask的对象)的route()方法。

# rule是路由
def route(self, rule, **options):
	# 定义decorator函数
    def decorator(f):
        endpoint = options.pop("endpoint", None)
        self.add_url_rule(rule, endpoint, f, **options)
        return f
	# 返回decorator函数
    return decorator

route()函数执行完后,视图函数就相当于下面:

@decorator
def hello_word():
    return 'Hello World!'

接着执行decorator(hello_word)

# f是视图函数(hello_word)
def decorator(f):
	# 取出别名,不传就为None
    endpoint = options.pop("endpoint", None)
    # self是app对象
    # 接着调用app对象的add_url_rule方法
    self.add_url_rule(rule, endpoint, f, **options)
    # 返回视图函数
    return f

接着调用app对象的add_url_rule方法。

def add_url_rule(self, rule, endpoint=None, view_func=None, provide_automatic_options=None, **options):
    if endpoint is None:
    	# 如果endpoint没传,就执行_endpoint_from_view_func方法
    	# _endpoint_from_view_func返回视图函数的视图名
    	# 所以不传endpoint参数,会以视图函数名作为endpoint
        endpoint = _endpoint_from_view_func(view_func)  # type: ignore
    options["endpoint"] = endpoint
    methods = options.pop("methods", None)
	
	# 如果没有传methods参数
    if methods is None:
    	# 就从视图函数中反射methods属性,没有的话就为一个元组("GET",)
        methods = getattr(view_func, "methods", None) or ("GET",)
    # methods不能是字符串
    if isinstance(methods, str):
        raise TypeError(
            "Allowed methods must be a list of strings, for"
            ' example: @app.route(..., methods=["POST"])'
        )
    # 这是一个集合生成式,保证集合里的元素不重复
    methods = {item.upper() for item in methods}

    # 添加必要的方法 也是一个集合
    required_methods = set(getattr(view_func, "required_methods", ()))

    # starting with Flask 0.8 the view_func object can disable and
    # force-enable the automatic options handling.
    if provide_automatic_options is None:
        provide_automatic_options = getattr(
            view_func, "provide_automatic_options", None
        )

    if provide_automatic_options is None:
        if "OPTIONS" not in methods:
            provide_automatic_options = True
            required_methods.add("OPTIONS")
        else:
            provide_automatic_options = False

    # Add the required methods now.
    # | 表示集合求并集
    methods |= required_methods
	
	# self.url_rule_class是Flask类实例化时设置的
	# url_rule_class = Rule
	# rule就是Rule实例化的对象
    rule = self.url_rule_class(rule, methods=methods, **options)
    rule.provide_automatic_options = provide_automatic_options  # type: ignore
    
	# self.url_map也是在Falsk实例化时设置的
	# self.url_map = self.url_map_class()
	 # url_map_class = Map
    self.url_map.add(rule)
    if view_func is not None:
    	# self.view_functions: t.Dict[str, t.Callable] = {} 是一个字典
        old_func = self.view_functions.get(endpoint)
        if old_func is not None and old_func != view_func:
            raise AssertionError(
                "View function mapping is overwriting an existing"
                f" endpoint function: {endpoint}"
            )
        # self.view_functions = {'别名':视图函数}
        self.view_functions[endpoint] = view_func

_endpoint_from_view_func(view_func)方法

def _endpoint_from_view_func(view_func: t.Callable) -> str:
    """Internal helper that returns the default endpoint for a given
    function.  This always is the function name.
    """
    # 断言视图函数不为空
    assert view_func is not None, "expected view func if endpoint is not provided."
    # 返回视图函数的函数名
    return view_func.__name__

总结:

路由注册其实就是调用了app对象的add_url_rule()方法,那么也可以不用装饰器的方式来注册路由。

app.add_url_rule('/user/<username>', view_func=show_user_profile)

app.route和app.add_url_rule参数:

rule:URL规则
view_func:视图函数名称
defaults = None:默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}
endpoint = None:名称
methods = None:允许的请求方式,如:["GET", "POST"]
strict_slashes:对URL最后的 / 符号是否严格要求
        @app.route('/index', strict_slashes=False)
        #访问http://www.xx.com/index/ 或http://www.xx.com/index均可
        @app.route('/index', strict_slashes=True)
        #仅访问http://www.xx.com/index
redirect_to:重定向到指定地址
		@app.route('/index/<int:nid>', redirect_to='/home/<nid>')

使用装饰器完成登录认证

from flask import Flask, render_template, request, redirect, session, url_for

app = Flask(__name__)
app.debug = True
app.secret_key = 'sdfsdfsdfsdf'

USERS = {
    1: {'name': '张三', 'age': 18, 'gender': '男', 'text': "道路千万条"},
    2: {'name': '李四', 'age': 28, 'gender': '男', 'text': "安全第一条"},
    3: {'name': '王五', 'age': 18, 'gender': '女', 'text': "行车不规范"},
}

from functools import wraps


def auth(func):
	# 这里如果不使用wraps装饰器,func视图函数就变成了inner
	# endpoint就会重复,程序就会报错
	# 这里不加就要在route函数中指定endpoint参数
    @wraps(func)
    def inner(*args, **kwargs):
        user = session.get('user_info')
        if user:
            res = func(*args, **kwargs)
            return res
        return redirect('/login')

    return inner


@app.route('/detail/<int:nid>', methods=['GET'])
@auth
def detail(nid):
    info = USERS.get(nid)
    return render_template('detail.html', info=info)


@app.route('/index', methods=['GET'])
@auth
def index():
    return render_template('index.html', user_dict=USERS)


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == "GET":
        return render_template('login.html')
    else:
        # request.query_string
        user = request.form.get('user')
        pwd = request.form.get('pwd')
        if user == 'xuxiaoxu' and pwd == '123':
            session['user_info'] = user
            return redirect('/index')
        return render_template('login.html', error='用户名或密码错误')


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

六 cbv写法

6.1 快速使用

from flask import Flask
from flask.views import MethodView

app = Flask(__name__)


class Test(MethodView):

    def get(self):
        return 'get'

    def post(self):
        return 'post'


app.add_url_rule(rule='/test', view_func=Test.as_view(name='test'))

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

6.2 cbv加装饰器

View/as_view

# cls是视图类
# 如果在视图类中配置了decorators属性
if cls.decorators:
	# 将as_view传入的name参数赋值给view函数的名字
    view.__name__ = name
    view.__module__ = cls.__module__
    # 循环拿出每一个装饰器函数
    for decorator in cls.decorators:
    	# 相当于		
		# @decorator 
		# def view():
		#     pass
        view = decorator(view)

6.3 as_view的执行流程

View/as_view

@classmethod
# 是一个类方法 
# cls是视图类,name必须传,不传会报错。
def as_view(cls, name, *class_args, **class_kwargs):
	# 定义view函数
    def view(*args, **kwargs):
        self = view.view_class(*class_args, **class_kwargs)  # type: ignore
        return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)
	
	# 如果有装饰器,在这里执行装饰器
    if cls.decorators:
        view.__name__ = name
        view.__module__ = cls.__module__
        for decorator in cls.decorators:
            view = decorator(view)
	# 修改和增加view函数的属性
    view.__name__ = name
    view.__doc__ = cls.__doc__
    view.__module__ = cls.__module__
    view.methods = cls.methods  # type: ignore
    view.provide_automatic_options = cls.provide_automatic_options  # type: ignore
    # 返回view函数
    return view

请求匹配成功,会执行as_view中的view

def view(*args, **kwargs):
	# view.view_class是在执行as_view赋值给view函数的,是视图类
	# 所以self就是视图类的对象
    self = view.view_class(*class_args, **class_kwargs)  # type: ignore
    # 先执行self.dispatch_request
    return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)

接着执行self.dispatch_request self是视图类的对象。

def dispatch_request(self, *args, **kwargs):
	# 从视图类对象中获取请求方式的视图函数内存地址
    meth = getattr(self, request.method.lower(), None)

    # If the request method is HEAD and we don't have a handler for it
    # retry with GET.
    if meth is None and request.method == "HEAD":
        meth = getattr(self, "get", None)

    assert meth is not None, f"Unimplemented method {request.method!r}"
    # 执行视图函数
    return current_app.ensure_sync(meth)(*args, **kwargs)

6.4 as_view的name参数

执行了as_view()函数,as_view的内层函数view的函数名就变成了name指定的值。

接着执行app.add_url_rule函数,如果没有指定endpoint参数,endpoint是view函数的函数名,就是as_view传的name参数。如果指定了endpoint参数,endpoint就是指定的endpoint参数值,和view的函数名就没有关系了。

6.5 继承View写cbv

from flask import Flask
from flask.views import View

app = Flask(__name__)


class Test(View):

    def get(self):
        return 'get'


app.add_url_rule('/test', view_func=Test.as_view(name='test'))

if __name__ == '__main__':
    app.run()
def dispatch_request(self) -> ResponseReturnValue:
    """Subclasses have to override this method to implement the
    actual view function code.  This method is called with all
    the arguments from the URL rule.
    """
    raise NotImplementedError()

在执行self.dispatch_request是或抛出NotImplementedError异常,继承View写cbv需要自己定制dispatch_request方法。

七 模板语法

7.1 渲染变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <table>
        {% for k,v in user_dict.items() %}
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v['name']}}</td>
            <td>{{v.get('name')}}</td>
            <td><a href="/detail/{{k}}">查看详细</a></td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>

7.2 变量的循环

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <table>
        {% for k,v in user_dict.items() %}
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v['name']}}</td>
            <td>{{v.get('name')}}</td>
            <td><a href="/detail/{{k}}">查看详细</a></td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>

7.3 逻辑判断

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>用户列表</h1>
    <table>
        {% if name %}
          <h1>Hello {{ name }}!</h1>
        {% else %}
          <h1>Hello World!</h1>
        {% endif %}
    </table>
</body>
</html>

比django中多可以加括号,执行函数,传参数

# Markup等价django的mark_safe 
from flask import Flask,render_template,Markup,jsonify,make_response
app = Flask(__name__)

def func1(arg):
    return Markup("<input type='text' value='%s' />" %(arg,))
@app.route('/')
def index():
    return render_template('index.html',ff = func1)

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fluent中模型设置和数据的复用

1 背景 在实际工程中&#xff0c;必然存在利用仿真比较各类设计方案优劣的场景。 对于复杂模型&#xff0c;逐个设置各个设计方案的仿真模型并从头开始计算结果&#xff0c;既易错也耗时。因此需要通过模型设置和数据的复用&#xff0c;达到防错和提高工作效率。 2 模型设置复…

基于Docker做MySQL主从搭建与Django的读写分离

目录 基于Docker做MySQL主从搭建 django读写分离 基于Docker做MySQL主从搭建 主从的作用&#xff1a;写数据数据时使用主库&#xff0c;从库只用来读数据&#xff0c;这样做能够减少数据库压力&#xff0c;主从搭建可以一主一从&#xff0c;也可以是一主多从。 mysql主从配…

肝2022世界杯,怒写企业级镜像私仓Docker+Harbor实践

2022-12-09 揭幕2022卡塔尔世界杯4强角逐的第一天&#xff0c;越来越精彩了 同时记录程序猿的成长~ 1.背景 由于期望搭建一个企业级CICD的环境&#xff0c;开始尝试常规的gitlabjenkinsk8sdocker harborspringboot开始练手 其中版本如下&#xff1a; 1.gitlab: GitLab Com…

天权信安catf1ag网络安全联合公开赛---wp

文章目录misc简单隐写十位马WebhistoryCrypto疑惑ezrsapasswdre遗失的物品misc 简单隐写 丢进kali binwalk 分离一下 得到一个加密的压缩包 内含flag.txt 使用jphs无密码得到一个txt 得到password:catf1agcatf1agcatf1ag 解压压缩包得到一串字符串 dbug1bh{KQit_x1o_Z0v_…

threejs官方demo学习(2):相机

webgl_camera 不知道是哪里写的有问题&#xff0c;最终的效果&#xff0c;跟官方案例有比较大的差距。不过可以学到的知识点挺多的。 知识点 CameraHelper 相机辅助对象&#xff0c;用于模拟相机视锥体 // 创建透视相机 cameraPerspective new THREE.PerspectiveCamera(5…

二叉树路径和(c#)

问题描述 给定一个二叉树的根和一个整数值&#xff0c;如果二叉树中有根节点到叶子节点的路径上节点值的和等于给定的整数值&#xff0c;则返回真&#xff0c;否则返回假。 叶子节点:没有孩子的节点。 示例 示例1 Input: root [5,4,8,11,null,13,4,7,2,null,null,null,1], t…

两个List<Integer>在相同的值比较返回值为false的问题解析

写在前面:今天刷LeetCode的时候发现一个测试用例始终过不去&#xff0c;代码出问题处大概表述如下: List<Integer> a new ArrayList<>(); a.add(300); List<Integer> b new ArrayList<>(); b.add(300); if(a.get(0) b.get(0)){ 代码块B } else{ 代…

[生成 pdf 详解]

目录 前言: pom需要的依赖: 测试类: 效果: 生成表格PDF: 其他复杂的格式就去研究那个 如何生成吧 测试类代码: 前言: 摸鱼来的 pom需要的依赖: <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><vers…

【计算机毕业设计】76.垃圾分类系统源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多国有企业的之中&#xff0c;随之就产生了“垃圾分类系统”&#xff0c;这样就让垃圾分类系统更…

web前端大作业:旅游网页主题网站设计——武汉旅游网页设计(11页)HTML+CSS+JavaScript

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

AWS CodeCommit SSH公钥配置

在本地计算机上的终端中&#xff0c;运行 ssh-keygen 命令&#xff0c;并按照说明将文件保存到您的配置文件的 .ssh 目录中。 其中windows用户可以使用git bash。 这会生成&#xff1a; codecommit_rsa 文件&#xff0c;该文件为私有密钥文件。 codecommit_rsa.pub 文件&#…

Android 搜索匹配的文字之后显示成红色

先简单看一下效果&#xff1a; 实现的主要代码&#xff1a; /*** * param color 需要提示的演示* param txt 字符串信息* param keyword 搜索的关键字* return*/ private SpannableString matchSearchText(int color, String txt, String keyword) {SpannableString spannableS…

基于springboot vue前后端分离的赛事疫情管理系统源码

开发工具&#xff1a;idea (eclipse) 环境&#xff1a;jdk1.8 mysql5.7&#xff0c; navcat 演示视频&#xff1a; 【java毕业设计】基于springboot vue前后端分离的赛事疫情管理系统源码许多年以前&#xff0c;人们在对数据进行统计和记录时候&#xff0c;使用的是纸和笔&…

抄袭、侵权、刷单,谁在洗地机的风口自乱了阵脚?

文|螳螂观察 作者| 陈淼 又一记法律重锤落下&#xff0c;追觅再次被敲在行业的耻辱柱上。 日前&#xff0c;添可和追觅的专利纠纷案迎来最新进展。根据裁定结果&#xff0c;追觅最终向宁波市中级人民法院作出承诺&#xff0c;于2022年10月30日起停止生产、销售四款涉案产品及…

基于碳库模拟、机器学习方法、生命周期评价法(LCA)、经验模型和过程模型的生态与农田温室气体排放的模拟

当前全球温室气体大幅升高&#xff0c;过去170年CO2浓度上升47%&#xff0c;这种极速变化使得物种和生态系统的适应时间大大缩短&#xff0c;进而造成全球气候变暖、海平面上升、作物产量降低、人类心血管和呼吸道疾病加剧等种种危害。生态与农业是甲烷&#xff08;CH4&#xf…

JMeter 的17种逻辑控制器,你用过哪个?

JMeter提供了17种逻辑控制器&#xff0c;它们各个功能都不尽相同&#xff0c;其作用域只对其子节点的sampler有效&#xff0c;作用是控制采样器的执行顺序。 控制测试计划执行过程中节点的逻辑执行顺序&#xff0c;如&#xff1a;Loop Controller、If Controller等&#xff1b…

2022世界物联网博览会|中国电信5G+AIoT创新科技齐上阵,亮点纷呈看不够

2022年无锡世界物联网博览会 正式拉开序幕 本次中国电信展台 以“智联万物 点亮未来”为主题 于无锡太湖国际博览中心B1-01展台 万里鹏翼&#xff0c;振翅而飞 为数智未来插上硬核翅膀&#xff01; 本次展会中国电信展台围绕“云改数转”、“网信安全”、“红色通信”、“…

SpringBoot+Vue实现前后端分离的校园外卖配送系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…

networkx学习(一) 图论

1.创建一个简单网络&#xff08;图&#xff09; # 导入库 import networkx as nx import matplotlib.pyplot as plt# 创建一个空图 G nx.Graph() # 向该图中添加节点和连边 G.add_nodes_from([1,2,3,4]) G.add_edges_from([(1,2),(1,3),(2,3),(2,4)])# 可视化图 nx.draw(G, n…

《Linux运维实战:MongoDB数据库逻辑备份恢复(方案四)》

一、备份与恢复方案 Percona Server for MongoDB Percona Server for MongoDB是一个免费的、增强的、完全兼容的、源代码可用的、带有企业级功能的MongoDB Community Edition的替代品。它不需要对MongoDB应用程序或代码进行更改。 参考官方&#xff1a;Percona Backup for Mon…