「Django框架」-视图函数FBV(flask 视图函数)
ccwgpt 2024-10-28 15:00 32 浏览 0 评论
函数视图
一个视图函数,简称视图,是一个简单的Python函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个 404 错误,一个 XML 文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。
应用程序目录中的名为views.py的文件中。
前面我们学习中视图都是通过定义函数来实现的,例如:
# views.py
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
username = request.POST.get('username')
pwd = request.POST.get('pwd')
if username and pwd:
res['user'] = username
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
res['msg'] = '用户名或密码错误'
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
# *************************
# urls.py
from .views import login
urlpatterns = [
path('login/', login, name='login')
]
http请求中产生两个核心对象:
1)HTTP 请求--->HttpRequest 对象,用户请求相关的所有信息(对象);
HTTP 协议以【请求 - 回复 】的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据 URL 来提供特定的服务。
一个请求的大概流程:
HTTP请求流程
通过 TCP 三次握手进行连接,然后开始传数据,客户端发送请求给服务器,服务器作出相应的相应返回给客户端。
2)HTTP 响应--->HttpResponse 对象,响应字符串。
如:
# views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("你好")
# 在urls.py中修改配置
from . import views
path('', views1.index, name='index'),
上面我们用到的request,就是HttpRequest对象。HttpResponse("你好"),就是HttpResponse对象,它向http请求响应了一段字符串。
视图函数,就是围绕着HttpRequest和HttpResponse这两个对象进行的。
HttpRequest 对象
Django在接收到http请求之后,Django会将http协议请求报文中的请求行、首部信息、内容主体封装到一个HttpRequest对象,并且将HttpRequest对象当作参数传给视图函数的第一个参数request。在视图函数中,通过访问该对象的属性便可以提取http请求数据。
常用属性
HttpRequest对象上大部分的属性都是只读的。因为这些属性是从客户端上传上来的,没必要做任何的修改。以下将对一些常用的属性进行讲解:
request.scheme:网络请求的协议,一般是http和https。
request.path:当前请求 URL 路径,但不包含协议和域名以及参数。比如https://www.qmpython.com/articles/detail-45.html,那么 path就是/articles/detail-45.html。
request.method:代表当前请求的http方法。一般是GET还是POST。
request.GET:一个类似于字典的django.http.request.QueryDict对象,可以通过访问字典的方式访问里面的值,里面的值是通过GET请求传递进来的参数(以?xxx=xxx的方式)。
# 当请求url为:http://www.qmpython.com:8004/user/index/3.html?a=1&b=2
print(request.GET) # 输出:<QueryDict: {'a': ['1'], 'b': ['2']}>
print(request.GET.get('a')) # 输出:1
print(request.GET.get('b')) # 输出:2
# 针对像这种,http://www.qmpython.com:8004/user/index/3.html?a=1&b=2&c=3&c=4&c=5,存在同个参数多个值的情况
print(request.GET) # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['3', '4', '5']}>
print(request.GET.get('a')) # 1
print(request.GET.get('b')) # 2
print(request.GET.getlist('c')) # ['3', '4', '5']
request.POST:一个类似于字典的django.http.request.QueryDict对象,封装了POST请求所包含的表单数据。注意,这个POST里面不包含上传的文件信息。
例如模板文件login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<h2>注册界面</h2>
<form action="" method="post">
{% csrf_token %} <!-- 必须加上这一行,后续会详细介绍 -->
用户名:<input type="text" name="username" placeholder="请输入账号"/><br/>
密 码:<input type="password" name="password"/><br/>
爱好:
<input type="checkbox" name="hobbies" value="music">音乐
<input type="checkbox" name="hobbies" value="read">阅读
<input type="checkbox" name="hobbies" value="dancing">跳舞
<br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
视图函数views.py:
def index(request, id):
if request.method == 'GET':
print(request.GET) # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['3', '4', '5']}>
print(request.GET.get('a')) # 1
print(request.GET.get('b')) # 2
print(request.GET.getlist('c')) # ['3', '4', '5']
return render(request, 'user/index.html')
elif request.method == 'POST':
print(request.POST)
# <QueryDict: {'csrfmiddlewaretoken': ['J390sN2dzBcW5lCg37ywxhrIVi3MXepLy1Qal7tYA8zYhVH9TJAdMfEV0SCgXqcM'],
# 'username': ['qmpython'], 'password': ['1234'], 'hobbies': ['music', 'dancing']}>
print(request.POST.get('username')) # qmpython
print(request.POST.get('password')) # 1234
print(request.POST.getlist('hobbies')) # ['music', 'dancing']
return HttpResponse('注册信息提交成功')
request.body:http请求中传递的原始数据,是一个byte类型的string。
当浏览器基于http协议的POST方法提交数据时,数据会被放到请求体中发送给Django,Django会将接收到的请求体数据存放于HttpRequest.body属性中,因为该属性的值为Bytes类型,所以通常情况下直接处理Bytes并从中提取有用数据的操作是复杂而繁琐的,好在Django会对它做进一步的处理与封装以便我们更为方便地提取数据,比如对于form表单来说,提交数据的常用方法为GET与POST。
1)如果表单属性method='GET',那么在提交表单时,表单内数据不会存放于请求体body中,而是会将表单数据按照k1=v1&k2=v2&k3=v3的格式放到url中,然后发送给Django,Django会将这些数据封装到request.GET中,注意此时的request.body为空,无用!模板文件中:
<!-- 如将之前的表单提交改成get方法 -->
<form action="" method="get">
...
</form>
<!--
输入地址:http://www.qmpython.com:8004/user/index/3.html?a=1&b=6
填写完用户名和密码,提交之后,表单数据按照k1=v1&k2=v2形式放到url后:
http://www.qmpython.com:8004/user/index/3.html?csrfmiddlewaretoken=ZpICWaQOnRqYfgQGbkgELZYyt6S4hajzSnEqYhv0qomjTmOChQFG4LMeXNDd54i0&username=qmpython&password=123456&hobbies=read&hobbies=dancing
原来的参数a,b被覆盖了!
-->
视图views.py中:
print(request.body) # b'' # get方式请求,请求数据不会放到body中
print(request.GET)
# <QueryDict: {'csrfmiddlewaretoken': ['ZpICWaQOnRqYfgQGbkgELZYyt6S4hajzSnEqYhv0qomjTmOChQFG4LMeXNDd54i0'], 'username': ['qmpython'], 'password': ['123456'], 'hobbies': ['read', 'dancing']}>
2)如果表单属性method='POST',那么在提交表单时,表单内的所有数据都会存放于请求体中,在发送给Django后会封装到request.body里,此时Django为了方便我们提取数据,会request.body的数据进行进一步的处理,具体如何处理呢,需要从form表单提交数据的编码格式说起:form表单对提交的表单数据有两种常用的编码格式,可以通过属性enctype进行设置,如下
- enctype="application/x-www-form-urlencoded"(默认的编码格式)。
- enctype="multipart/form-data"(使用form表单上传文件时只能用该编码)。
如果form表单提交数据是按照第一种方式,那么request.body中数据的格式类似于GET方法的数据格式,如k1=v1&k2=v2,此时Django会将request.body中的数据提取出来封装到request.POST中方便我们提取。
<!-- 如将之前的表单提交改成get方法 -->
<form action="" method="post">
...
</form>
视图中:
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
print(request.body) #b'csrfmiddlewaretoken=JbgAeQk8IMiCvn6uxBuM6mMix9l1U4Lpy9XK7aLTJjFEHXbnndwtlkZvCJUvUgyq&username=admin&password=123456'
print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['JbgAeQk8IMiCvn6uxBuM6mMix9l1U4Lpy9XK7aLTJjFEHXbnndwtlkZvCJUvUgyq'], 'username': ['admin'], 'password': ['123456']}>
return HttpResponse('登录成功')
request.FILES:也是一个类似于字典的django.http.request.QueryDict对象。这个属性中包含了所有上传的文件。如果使用form表单POST上传文件的话,文件数据将包含在request.Files属性中。只有在请求的方法为POST 且提交的form表单带有enctype="multipart/form-data"的情况下才会包含数据,否则,FILES将为一个空的类似于字典的对象。
该属性值为一个类似于字典的对象,可以包含多组key:value(对应多个上传的文件),其中每个key为<input type="file" name="" />中name属性的值,而value则为对应的文件数据。
<form action="" method="post" enctype="multipart/form-data">
头像:<input type="file" name="head_img">
</form>
#views.py
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
elif request.method == 'POST':
#print(request.body)
print(request.POST) # <QueryDict: {'csrfmiddlewaretoken': ['yIpuMsAdApp1mPt9tqEHJxXUkLxmS7t3CebPbZhWz6TIaKoDJTMTHG9oBkugHxnt'], 'username': ['admin'], 'password': ['123456']}>
print(request.POST.get('username')) # admin
print(request.FILES) # <MultiValueDict: {'head_img': [<InMemoryUploadedFile: DSP_IP.jpg (image/jpeg)>]}>
print(request.FILES.get('head_img')) # DSP_IP.jpg
# 然后可以使用文件写入模块write
return HttpResponse('登录成功')
request.COOKIES:一个标准的Python字典,包含所有的cookie信息,键值对都是字符串类型。
request.session:返回一个QueryDict的类字典类型的集合,用来操作服务器的session,这个属性要有效,必须添加SessionMiddleware这个中间件。
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
...
]
request.user:user 只有当Django启用 AuthenticationMiddleware 中间件时才可用。它的值是一个 setting.py 里面AUTH_USER_MODEL 字段所定义的类的对象,表示当前登录的用户。如果用户当前没有登录,user 将设为 django.contrib.auth.models.AnonymousUser 的一个实例。可以通过 is_authenticated() 区分它们。
MIDDLEWARE = [
...
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
request.META:一个标准的 Python 字典,包含所有的 HTTP 首部,具体的头部信息取决于客户端和服务器。
CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。CONTENT_TYPE —— 请求的正文的MIME 类型。HTTP_ACCEPT —— 响应可接收的Content-Type。HTTP_ACCEPT_ENCODING —— 响应可接收的编码。HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。HTTP_HOST —— 客服端发送的HTTP Host 头部。HTTP_REFERER —— Referring 页面。HTTP_USER_AGENT —— 客户端的user-agent 字符串。QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。REMOTE_ADDR —— 客户端的IP 地址。REMOTE_HOST —— 客户端的主机名。REMOTE_USER —— 服务器认证后的用户。REQUEST_METHOD —— 一个字符串,例如”GET“ 或”POST“。SERVER_NAME —— 服务器的主机名。SERVER_PORT —— 服务器的端口(是一个字符串)。
上面,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀。
所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
超实用例子:
如果服务器使用了nginx做反向代理或者负载均衡,那么这个值返回的是127.0.0.1 ,这时候可以使用HTTP_X_FORWARDED_FOR来获取,所以获取 ip 地址的代码片段如下:
#获取IP
if 'HTTP_X_FORWARDED_FOR' in request.META:
ip = request.META['HTTP_X_FORWARDED_FOR']
else:
ip = request.META['REMOTE_ADDR']
常用方法
request.is_secure():是否是采用https协议。
request.is_ajax():是否采用ajax发送的请求。原理就是判断请求头中是否存在X-Requested-With:XMLHttpRequest。
request.get_host():服务器的域名。如果在访问的时候还有端口号,那么会加上端口号。比如www.qmpython.com:9000。
request.get_full_path():获取url地址的完整path。如果有查询字符串,还会加上查询字符串。比如/music/bands/?print=True。
request.get_raw_uri():获取请求的完整url。
# 如果请求地址是:http://www.qmpython.com:8004/user/index/3.html?a=1&b=6
print(request.path) # /user/index/3.html
print(request.get_full_path()) # /user/index/3.html?a=1&b=6
print(request.get_raw_uri()) # http://www.qmpython.com:8004/user/index/3.html?a=1&b=6
HttpResponse 对象
Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个HttpRequest对象传给视图函数。那么视图函数在处理完相关的逻辑后,也需要返回一个响应给浏览器。而这个响应,我们必须返回HttpResponseBase或者他的子类的对象。相应对象主要有三种形式:HttpResponse,render,redirect。而HttpResponse则是HttpResponseBase用得最多的子类。那么接下来就来介绍一下HttpResponse及其子类。
常用属性
content:代表要发送给客户端的内容。
status_code:返回的 HTTP 响应状态码。
content_type:返回的数据的 MIME 类型,返回的数据的 MIME 类型,默认为text/html;charset=utf-8。浏览器会根据这个属性,来显示数据。如果是text/html,那么就会解析这个字符串,如果text/plain,那么就会显示一个纯文本。常用的Content-Type如下:
- text/html(默认的,html 文件)
- text/plain(纯文本)
- text/css(css 文件)
- text/javascript(js 文件)
- multipart/form-data(文件提交)
- application/json(json 传输)
- application/xml(xml 文件)
设置请求头:response['X-Access-Token'] = 'xxxx'。
charset:响应体的编码,如果没有指定,则会使用content_type中设置的charset。
常用方法
render:将指定页面渲染后返回给浏览器。
render(request, template_name[, context])
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的HttpResponse对象。
def index(request):
articles = Article.objects.all().order_by('-id')
print(request.body)
context = {
'articles':articles,
}
return render(request, 'index.html',context)
参数:request:用于生成响应的请求对象。template_name:要使用的模板的完整名称,可选的参数context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。status:响应的状态码。默认为 200。
render方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的 html静态文件返回给浏览器。这里一定要注意:render渲染的是模板。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>博客首页</title>
</head>
<body>
<div style="margin: 0 auto">
<ul>
<h3>最新文章</h3>
{% for article in articles %}
<li>{{ x.article }}</li>
{% endfor %}
</ul>
</div>
</body>
</html>
上面 {}之间包括的就是我们要从数据库取出的数据,进行填充。对于这样一个没有填充数据的html文件,浏览器是不能进行渲染的,所以,对于上述{}之间的内容先要被render进行渲染之后,才能发送给浏览器。
redirect:多用于页面跳转。
redirect的参数可以是:一个模型:将调用模型的get_absolute_url() 函数。
from django.shortcuts import redirect
def my_view(request):
...
# 传递一个对象,将调用get_absolute_url() 方法来获取重定向的URL
object = MyModel.objects.get(...)
return redirect(object)
一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称。
def my_view(request):
...
return redirect('some-view-name', foo='bar')
一个绝对的或相对的URL,将原封不动的作为重定向的位置。
def my_view(request):
...
return redirect('/some/url/')
# return redirect('https://www.django.cn/')
默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。
重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面。
- 永久性重定向:http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京东网站,你输入www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个网址已经被废弃了,被改成jd.com,所以这种情况下应该用永久重定向。
- 暂时性重定向:http的状态码是302,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
在Django中,重定向是使用redirect(to, *args, permanent=False, **kwargs)来实现的。to是一个url,permanent代表的是这个重定向是否是一个永久的重定向,默认是False。关于重定向的使用。请看以下例子:
from django.shortcuts import reverse,redirect
def profile(request):
if request.GET.get("username"):
return HttpResponse("%s,欢迎来到个人中心页面!")
else:
return redirect(reverse("user:login"))
render和redirect两者区别: 第一,假如render返回一个登陆成功后的页面,刷新该页面将回复到跳转前页面。而 redirect 则不会 第二,如果页面需要模板语言渲染,需要的将数据库的数据加载到html,那么render方法则不会显示这一部分,render返回一个登陆成功页面,不会经过url路由分发系统,也就是说,不会执行跳转后url的视图函数。这样,返回的页面渲染不成功;而redirect是跳转到指定页面,当登陆成功后,会在url路由系统进行匹配,如果有存在的映射函数,就会执行对应的映射函数。
set_cookie:用来设置cookie信息。后面讲到授权的时候会着重讲到。
delete_cookie:用来删除cookie信息。
write:HttpResponse是一个类似于文件的对象,可以用来写入数据到数据体(content)中。
Django 限制请求 method
常用的请求 method
GET请求:一般用来向服务器获取数据,但不会向服务器提交数据,不会对服务器的状态进行更改。比如向服务器获取某篇文章的详情。
POST请求:一般是用来向服务器提交数据,会对服务器的状态进行更改。比如提交一篇文章给服务器。
限制请求装饰器
Django内置的视图装饰器可以给视图提供一些限制。比如这个视图只能通过GET的method访问等。以下将介绍一些常用的内置视图装饰器。
1)django.http.decorators.http.require_http_methods:这个装饰器需要传递一个允许访问的方法的列表。比如只能通过GET的方式访问。那么示例代码如下:
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET"])
def my_view(request):
pass
2)django.views.decorators.http.require_GET:这个装饰器相当于是require_http_methods(['GET'])的简写形式,只允许使用GET的method来访问视图。示例代码如下:
from django.views.decorators.http import require_GET
@require_GET
def my_view(request):
pass
3)django.views.decorators.http.require_POST:这个装饰器相当于是require_http_methods(['POST'])的简写形式,只允许使用POST的method来访问视图。示例代码如下:
from django.views.decorators.http import require_POST
@require_POST
def my_view(request):
pass
4)django.views.decorators.http.require_safe:这个装饰器相当于是require_http_methods(['GET','HEAD'])的简写形式,只允许使用相对安全的方式来访问视图。因为GET和HEAD不会对服务器产生增删改的行为。因此是一种相对安全的请求方式。示例代码如下:
from django.views.decorators.http import require_safe
@require_safe
def my_view(request):
pass
公众号: Python野路子
野路子学习整理和分享Python入门和Python Web开发以及Python爬虫相关知识。欢迎互相学习交流,共同进步~~
相关推荐
- 用Steam启动Epic游戏会更快吗?(epic怎么用steam启动)
-
Epic商店很香,但也有不少抱怨,其中一条是启动游戏太慢。那么,如果让Steam启动Epic游戏,会不会速度更快?众所周知,Steam可以启动非Steam游戏,方法是在客户端左下方点击“添加游戏”,然...
- Docker看这一篇入门就够了(dockerl)
-
安装DockerLinux:$curl-fsSLhttps://get.docker.com-oget-docker.sh$sudoshget-docker.sh注意:如果安装了旧版...
- AYUI 炫丽PC开发UI框架2016年6月15日对外免费开发使用 [1]
-
2016年6月15日,我AY对外发布AYUI(WPF4.0开发)的UI框架,开发时候,你可以无任何影响的去开发PC电脑上的软件exe程序。AYUI兼容XP操作系统,在Win7/8/8.1/10上都顺利...
- 别再说C#/C++套壳方案多了!Tauri这“借壳生蛋”你可能没看懂!
-
浏览器套壳方案,C#和C++有更多,你说的没错,从数量和历史积淀来看,C#和C++确实有不少方式来套壳浏览器,让Web内容在桌面应用里跑起来。但咱们得把这套壳二字掰扯清楚,因为这里面学问可大了!不同的...
- OneCode 核心概念解析——Page(页面)
-
在接触到OneCode最先接触到的就是,Page页面,在低代码引擎中,页面(Page)设计的灵活性是平衡“快速开发”与“复杂需求适配”的关键。以下从架构设计、组件系统、配置能力等维度,解析确...
- React是最后的前端框架吗,为什么这么说的?
-
油管上有一位叫Theo的博主说,React是终极前端框架,为什么这么说呢?让我们来看看其逻辑:这个标题看起来像假的,对吧?React之后明明有无数新框架诞生,凭什么说它是最后一个?我说的“最后一个”不...
- 面试辅导(二):2025前端面试密码:用3个底层逻辑征服技术官
-
面试官放下简历,手指在桌上敲了三下:"你上次解决的技术难题,现在回头看有什么不足?"眼前的候选人瞬间僵住——这是上周真实发生在蚂蚁金服终面的场景。2025年的前端战场早已不是框架熟练...
- 前端新星崛起!Astro框架能否终结React的霸主地位?
-
引言:当"背着背包的全能选手"遇上"轻装上阵的短跑冠军"如果你是一名前端开发者,2024年的框架之争绝对让你眼花缭乱——一边是React这位"背着全家桶的全能选...
- 基于函数计算的 BFF 架构(基于函数计算的 bff 架构是什么)
-
什么是BFFBFF全称是BackendsForFrontends(服务于前端的后端),起源于2015年SamNewman一篇博客文章《Pattern:BackendsFor...
- 谷歌 Prompt Engineering 白皮书:2025年 AI 提示词工程的 10 个技巧
-
在AI技术飞速发展的当下,如何更高效地与大语言模型(LLM)沟通,以获取更准确、更有价值的输出,成为了一个备受关注的问题。谷歌最新发布的《PromptEngineering》白皮书,为这一问题提供了...
- 光的艺术:灯具创意设计(灯光艺术作品展示)
-
本文转自|艺术与设计微信号|artdesign_org_cn“光”是文明的起源,是思维的开端,同样也是人类睁眼的开始。每个人在出生一刻,便接受了光的照耀和洗礼。远古时候,人们将光奉为神明,用火来...
- MoE模型已成新风口,AI基础设施竞速升级
-
机器之心报道编辑:Panda因为基准测试成绩与实际表现相差较大,近期开源的Llama4系列模型正陷入争议的漩涡之中,但有一点却毫无疑问:MoE(混合专家)定然是未来AI大模型的主流范式之一。...
- Meta Spatial SDK重大改进:重塑Horizon OS应用开发格局
-
由文心大模型生成的文章摘要Meta持续深耕SpatialSDK技术生态,提供开自去年9月正式推出以来,Meta持续深耕其SpatialSDK技术生态,通过一系列重大迭代与功能增强,不断革新H...
- "上云"到底是个啥?用"租房"给你讲明白IaaS/PaaS/SaaS的区别
-
半夜三点被机房报警电话惊醒,顶着黑眼圈排查服务器故障——这是十年前互联网公司运维的日常。而现在,程序员小王正敷着面膜刷剧,因为公司的系统全"搬"到了云上。"部署到云上"...
- php宝塔搭建部署thinkphp机械设备响应式企业网站php源码
-
大家好啊,欢迎来到web测评。本期给大家带来一套php开发的机械设备响应式企业网站php源码,上次是谁要的系统项目啊,帮你找到了,还说不会搭建,让我帮忙录制一期教程,趁着今天有空,简单的录制测试了一下...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 用Steam启动Epic游戏会更快吗?(epic怎么用steam启动)
- Docker看这一篇入门就够了(dockerl)
- AYUI 炫丽PC开发UI框架2016年6月15日对外免费开发使用 [1]
- 别再说C#/C++套壳方案多了!Tauri这“借壳生蛋”你可能没看懂!
- OneCode 核心概念解析——Page(页面)
- React是最后的前端框架吗,为什么这么说的?
- 面试辅导(二):2025前端面试密码:用3个底层逻辑征服技术官
- 前端新星崛起!Astro框架能否终结React的霸主地位?
- 基于函数计算的 BFF 架构(基于函数计算的 bff 架构是什么)
- 谷歌 Prompt Engineering 白皮书:2025年 AI 提示词工程的 10 个技巧
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)