Django DRF路由與擴(kuò)展功能的實(shí)現(xiàn)
一. 視圖集與路由的使用
使用視圖集ViewSet,可以將一系列邏輯相關(guān)的動(dòng)作放到一個(gè)類(lèi)中:
- list() 提供一組數(shù)據(jù)
- retrieve() 提供單個(gè)數(shù)據(jù)
- create() 創(chuàng)建數(shù)據(jù)
- update() 保存數(shù)據(jù)
- destory() 刪除數(shù)據(jù)
ViewSet視圖集類(lèi)不再實(shí)現(xiàn)get()、post()等方法,而是實(shí)現(xiàn)動(dòng)作 action 如 list() 、create() 等。
視圖集只在使用as_view()方法的時(shí)候,才會(huì)將action動(dòng)作與具體請(qǐng)求方式對(duì)應(yīng)上。
1. 常用的視圖集父類(lèi)
1.ViewSet
繼承自APIView 與 ViewSetMixin作用也與APIView基本類(lèi)似,提供了身份認(rèn)證、權(quán)限校驗(yàn)、流量管理等。
ViewSet主要通過(guò)繼承ViewSetMixin來(lái)實(shí)現(xiàn)在調(diào)用as_view()時(shí)傳入字典(如{'get':'list'})的映射處理工作。
在ViewSet中,沒(méi)有提供任何動(dòng)作action方法,需要我們自己實(shí)現(xiàn)action方法。
2.GenericViewSet
使用ViewSet通常并不方便,因?yàn)閘ist、retrieve、create、update、destory等方法都需要自己編寫(xiě),而這些方法與前面講過(guò)的Mixin擴(kuò)展類(lèi)提供的方法同名,所以我們可以通過(guò)繼承Mixin擴(kuò)展類(lèi)來(lái)復(fù)用這些方法而無(wú)需自己編寫(xiě)。但是Mixin擴(kuò)展類(lèi)依賴(lài)與GenericAPIView,所以還需要繼承GenericAPIView。
GenericViewSet就幫助我們完成了這樣的繼承工作,繼承自GenericAPIView與ViewSetMixin,在實(shí)現(xiàn)了調(diào)用as_view()時(shí)傳入字典(如{'get':'list'})的映射處理工作的同時(shí),還提供了GenericAPIView提供的基礎(chǔ)方法,可以直接搭配Mixin擴(kuò)展類(lèi)使用。
3.ModelViewSet
繼承自GenericViewSet,同時(shí)包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
4.ReadOnlyModelViewSet
繼承自GenericViewSet,同時(shí)包括了ListModelMixin、RetrieveModelMixin。
下面我們還是通過(guò)案例,為大家演示吧!
首先,先創(chuàng)建一個(gè)子應(yīng)用。
python3 manage.py startapp collect
5. 在collect下新建序列化器類(lèi)
# collect下的serializers.py文件
from students.models import Student
from rest_framework import serializers
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ["id", "name", "age", "sex"]
extra_kwargs = {
"name": {"max_length": 10, "min_length": 4},
"age": {"max_value": 150, "min_value": 0},
}
def validate_name(self, data):
if data == "root":
raise serializers.ValidationError("用戶(hù)名不能為root!")
return data
def validate(self, attrs):
name = attrs.get('name')
age = attrs.get('age')
if name == "alex" and age == 22:
raise serializers.ValidationError("alex在22時(shí)的故事。。。")
return attrs
class StudentInfoModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ["id", "name"]
6. collect下的urls.py
from django.urls import path, re_path
from collect import views
urlpatterns = [
# 不要在同一個(gè)路由的as_view中書(shū)寫(xiě)兩個(gè)同樣的鍵的http請(qǐng)求,會(huì)產(chǎn)生覆蓋!?。?
# ViewSet
path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),
path('student1/get_5_girl/', views.Student1ViewSet.as_view({"get": "get_5_girl"})),
re_path(r'^student1/(?P<pk>\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),
# GenericViewSet
path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),
path('student2/get_5_girl/', views.Student3GenericViewSet.as_view({"get": "get_5_girl"})),
# GenericViewSet,可以和模型類(lèi)進(jìn)行組合快速生成基本的API接口
path("students3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
# ModelViewSet 默認(rèn)提供了5個(gè)API接口
path("students4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
re_path(r"^students4/(?P<pk>\d+)/$", views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
# ReadOnlyModelViewSet
path("students5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
re_path(r"^students5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
# 一個(gè)視圖類(lèi)中調(diào)用多個(gè)序列化器
path("student8/", views.Student8GenericAPIView.as_view()),
# 一個(gè)視圖集中調(diào)用多個(gè)序列化器
path("student9/", views.Student9ModelViewSet.as_view({"get": "list"})),
re_path(r"^student9/(?P<pk>\d+)/$", views.Student9ModelViewSet.as_view({"get": "retrieve"})),
]
"""
有了視圖集以后,視圖文件中多個(gè)視圖類(lèi)可以合并成一個(gè),但是,路由的代碼就變得復(fù)雜了,
需要我們經(jīng)常在as_view方法 ,編寫(xiě)http請(qǐng)求和視圖方法的對(duì)應(yīng)關(guān)系,
事實(shí)上,在路由中,DRF也提供了一個(gè)路由類(lèi)給我們對(duì)路由的代碼進(jìn)行簡(jiǎn)寫(xiě)。
當(dāng)然,這個(gè)路由類(lèi)僅針對(duì)于 視圖集 才可以使用。
"""
# 路由類(lèi)默認(rèn)只會(huì)給視圖集中的基本5個(gè)API生成地址[ 獲取一條,獲取多條,添加.刪除,修改數(shù)據(jù) ]
from rest_framework.routers import DefaultRouter
# 實(shí)例化路由類(lèi)
router = DefaultRouter()
# router.register("訪問(wèn)地址前綴","視圖集類(lèi)","訪問(wèn)別名")
# 注冊(cè)視圖視圖集類(lèi)
router.register("student7", views.Student7ModelViewSet)
# 把路由列表注冊(cè)到django項(xiàng)目中
urlpatterns += router.urls
7. collect下的views.py
"""ViewSet視圖集,繼承于APIView,所以APIView有的功能,它都有,APIView沒(méi)有的功能,它也沒(méi)有"""
from rest_framework.viewsets import ViewSet
from students.models import Student
from .serializers import StudentModelSerializer
from rest_framework.response import Response
class Student1ViewSet(ViewSet):
def get_5(self, request):
student_list = Student.objects.all()[:5]
serializer = StudentModelSerializer(instance=student_list, many=True)
return Response(serializer.data)
def get_one(self, request, pk):
student = Student.objects.get(pk=pk)
serializer = StudentModelSerializer(instance=student)
return Response(serializer.data)
def get_5_girl(self, request):
student_list = Student.objects.filter(sex=False)[:5]
serializer = StudentModelSerializer(instance=student_list, many=True)
return Response(serializer.data)
"""如果希望在視圖集中調(diào)用GenericAPIView的功能,則可以采用下面方式"""
from rest_framework.generics import GenericAPIView
class Student2ViewSet(ViewSet, GenericAPIView):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
def get_5(self, request):
student_list = self.get_queryset()[:5]
serializer = StudentModelSerializer(instance=student_list, many=True)
return Response(serializer.data)
def get_one(self, request, pk):
student = self.get_object()
serializer = StudentModelSerializer(instance=student)
return Response(serializer.data)
def get_5_girl(self, request):
student_list = self.get_queryset().filter(sex=False)[:5]
serializer = StudentModelSerializer(instance=student_list, many=True)
return Response(serializer.data)
"""
上面的方式,雖然實(shí)現(xiàn)視圖集中調(diào)用GenericAPIView,但是我們要多了一些類(lèi)的繼承。
所以我們可以直接繼承 GenericViewSet
"""
from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
serializer_class = StudentModelSerializer
queryset = Student.objects.all()
def get_5(self, request):
student_list = self.get_queryset()[:5]
serializer = self.get_serializer(instance=student_list, many=True)
return Response(serializer.data)
def get_5_girl(self, request):
student_list = self.get_queryset().filter(sex=False)[:5]
serializer = self.get_serializer(instance=student_list, many=True)
return Response(serializer.data)
"""
在使用GenericViewSet時(shí),雖然已經(jīng)提供了基本調(diào)用數(shù)據(jù)集(queryset)和序列化器屬性,但是我們要編寫(xiě)一些基本的
API時(shí),還是需要調(diào)用DRF提供的模型擴(kuò)展類(lèi) [Mixins]
"""
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# 只讀模型視圖集
from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# 路由的使用
from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# methods 指定允許哪些http請(qǐng)求訪問(wèn)當(dāng)前視圖方法
# detail 指定生成的路由地址中是否要夾帶pk值,True為需要
@action(methods=["GET"], detail=False)
def get_6(self, request):
serilizer = self.get_serializer(instance=self.get_queryset().get(pk=6))
return Response(serilizer.data)
"""在多個(gè)視圖類(lèi)合并成一個(gè)視圖類(lèi)以后,那么有時(shí)候會(huì)出現(xiàn)一個(gè)類(lèi)中需要調(diào)用多個(gè)序列化器"""
"""1. 在視圖類(lèi)中調(diào)用多個(gè)序列化器"""
"""原來(lái)的視圖類(lèi)中基本上一個(gè)視圖類(lèi)只會(huì)調(diào)用一個(gè)序列化器,當(dāng)然也有可能要調(diào)用多個(gè)序列化器"""
from .serializers import StudentInfoModelSerializer
class Student8GenericAPIView(GenericAPIView):
queryset = Student.objects.all()
# GenericAPI內(nèi)部調(diào)用序列化器的方法,我們可以重寫(xiě)這個(gè)方法來(lái)實(shí)現(xiàn)根據(jù)不同的需求來(lái)調(diào)用不同的序列化器
def get_serializer_class(self):
if self.request.method == "GET":
# 2個(gè)字段
return StudentInfoModelSerializer
return StudentModelSerializer
def get(self, request):
"""獲取所有數(shù)據(jù)的id和name"""
student_list = self.get_queryset()
serializer = self.get_serializer(instance=student_list, many=True)
return Response(serializer.data)
def post(self, request):
"""添加數(shù)據(jù)"""
data = request.data
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
"""2. 在一個(gè)視圖集中調(diào)用多個(gè)序列化器"""
class Student9ModelViewSet(ModelViewSet):
queryset = Student.objects.all()
"""要求:
列表數(shù)據(jù)list,返回2個(gè)字段,
詳情數(shù)據(jù)retrieve,返回所有字段,
"""
def get_serializer_class(self):
# 本次客戶(hù)端請(qǐng)求的視圖方法名 self.action
if self.action == "list":
return StudentInfoModelSerializer
return StudentModelSerializer
二. 擴(kuò)展功能
為了方便接下來(lái)的學(xué)習(xí),我們創(chuàng)建一個(gè)新的子應(yīng)用 opt
python3 manage.py startapp opt
因?yàn)榻酉聛?lái)的功能中需要使用到登錄功能,所以我們使用django內(nèi)置admin站點(diǎn)并創(chuàng)建一個(gè)管理員.
創(chuàng)建管理員以后,訪問(wèn)admin站點(diǎn),先修改站點(diǎn)的語(yǔ)言配置,在settings里修改
LANGUAGE_CODE = 'zh-hans'
1. 認(rèn)證Authentication
可以在配置文件中配置全局默認(rèn)的認(rèn)證方案
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', # session認(rèn)證
'rest_framework.authentication.BasicAuthentication', # 基本認(rèn)證
)
}
也可以在每個(gè)視圖中通過(guò)設(shè)置authentication_classess屬性來(lái)設(shè)置
opt下的urls.py
from django.urls import path
from opt import views
urlpatterns = [
path('auth1/', views.Demo1APIView.as_view()),
path('auth2/', views.Demo2APIView.as_view()),
]
opt下的views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser
"""用戶(hù)的認(rèn)證和權(quán)限識(shí)別"""
class Demo1APIView(APIView):
"""只允許登錄后的用戶(hù)訪問(wèn)"""
permission_classes = [IsAuthenticated]
def get(self, request):
"""個(gè)人中心"""
return Response("個(gè)人中心")
class Demo2APIView(APIView):
"""只允許管理員訪問(wèn)"""
permission_classes = [IsAdminUser]
def get(self, request):
"""個(gè)人中心2"""
return Response("個(gè)人中心2")
2. 權(quán)限Permissions
權(quán)限控制可以限制用戶(hù)對(duì)于視圖的訪問(wèn)和對(duì)于具體數(shù)據(jù)對(duì)象的訪問(wèn)。
- 在執(zhí)行視圖的dispatch()方法前,會(huì)先進(jìn)行視圖訪問(wèn)權(quán)限的判斷
- 在通過(guò)get_object()獲取具體對(duì)象時(shí),會(huì)進(jìn)行模型對(duì)象訪問(wèn)權(quán)限的判斷
內(nèi)置提供的權(quán)限:
- AllowAny 允許所有用戶(hù)
- IsAuthenticated 僅通過(guò)認(rèn)證的用戶(hù)
- IsAdminUser 僅管理員用戶(hù)
- IsAuthenticatedOrReadOnly 已經(jīng)登陸認(rèn)證的用戶(hù)可以對(duì)數(shù)據(jù)進(jìn)行增刪改操作,沒(méi)有登陸認(rèn)證的只能查看數(shù)據(jù)。
可以在配置文件中全局設(shè)置默認(rèn)的權(quán)限管理類(lèi),如:
REST_FRAMEWORK = {
....
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
如果未指明,則采用如下默認(rèn)配置
'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.AllowAny', )
也可以在具體的視圖中通過(guò)permission_classes屬性來(lái)設(shè)置。
opt下的urls.py
urlpatterns = [
path('auth1/', views.Demo1APIView.as_view()),
path('auth2/', views.Demo2APIView.as_view()),
# 自定義權(quán)限
path('auth3/', views.Demo3APIView.as_view()),
]
opt下的views.py
# 自定義權(quán)限
from rest_framework.permissions import BasePermission
class MyPermission(BasePermission):
def has_permission(self, request, view):
"""
針對(duì)訪問(wèn)視圖進(jìn)行權(quán)限判斷
:param request: 本次操作的http請(qǐng)求對(duì)象
:param view: 本次訪問(wèn)路由對(duì)應(yīng)的視圖對(duì)象
:return:
"""
if request.user.username == "xiaoming":
return True
return False
class Demo3APIView(APIView):
permission_classes = [MyPermission]
def get(self, request):
"""個(gè)人中心3"""
return Response("個(gè)人中心3")
3. 限流Throttling
可以對(duì)接口訪問(wèn)的頻次進(jìn)行限制,以減輕服務(wù)器壓力。
一般用于付費(fèi)購(gòu)買(mǎi)次數(shù),投票等場(chǎng)景使用.
可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES進(jìn)行全局配置
REST_FRAMEWORK = {
# 限流
'DEFAULT_THROTTLE_CLASSES': ( # 對(duì)全局進(jìn)行設(shè)置
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/hour',
'user': '3/minute',
}
}
DEFAULT_THROTTLE_RATES 可以使用 second, minute, hour 或day來(lái)指明周期。
也可以在具體視圖中通過(guò)throttle_classess屬性來(lái)配置
opt下的urls.py
urlpatterns = [
path('auth1/', views.Demo1APIView.as_view()),
path('auth2/', views.Demo2APIView.as_view()),
# 自定義權(quán)限
path('auth3/', views.Demo3APIView.as_view()),
# 限流
path('auth4/', views.Demo4APIView.as_view()),
]
opt下的views.py
# 限流
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
# throttle_classes = [UserRateThrottle, AnonRateThrottle] # 全局配置后,這里就不用指定
def get(self, request):
"""投票頁(yè)面"""
return Response("投票頁(yè)面")
4. 過(guò)濾Filtering
對(duì)于列表數(shù)據(jù)可能需要根據(jù)字段進(jìn)行過(guò)濾,我們可以通過(guò)添加django-fitlter擴(kuò)展來(lái)增強(qiáng)支持。
pip3 install django-filter
在配置文件里進(jìn)行注冊(cè)
INSTALLED_APPS = [
...
'django_filters', # 需要注冊(cè)應(yīng)用,
]
REST_FRAMEWORK = {
...
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
在視圖中添加filter_fields屬性,指定可以過(guò)濾的字段。
opt下的urls.py
urlpatterns = [
path('auth1/', views.Demo1APIView.as_view()),
path('auth2/', views.Demo2APIView.as_view()),
# 自定義權(quán)限
path('auth3/', views.Demo3APIView.as_view()),
# 限流
path('auth4/', views.Demo4APIView.as_view()),
# 過(guò)濾
path('data5/', views.Demo5APIView.as_view()),
]
opt下的views.py
# 過(guò)濾 from rest_framework.generics import GenericAPIView, ListAPIView from students.models import Student from .serializers import StudentModelSerializer from django_filters.rest_framework import DjangoFilterBackend class Demo5APIView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer filter_backends = [DjangoFilterBackend] # 全局配置后,這里就不用指定了。 filter_fields = ['age', "id"] # 聲明過(guò)濾字段
5. 排序Ordering
對(duì)于列表數(shù)據(jù),REST framework提供了OrderingFilter過(guò)濾器來(lái)幫助我們快速指明數(shù)據(jù)按照指定字段進(jìn)行排序。
使用方法:
在類(lèi)視圖中設(shè)置filter_backends,使用rest_framework.filters.OrderingFilter過(guò)濾器,REST framework會(huì)在請(qǐng)求的查詢(xún)字符串參數(shù)中檢查是否包含了ordering參數(shù),如果包含了ordering參數(shù),則按照ordering參數(shù)指明的排序字段對(duì)數(shù)據(jù)集進(jìn)行排序。
前端可以傳遞的ordering參數(shù)的可選字段值需要在ordering_fields中指明。
opt下的urs.py
urlpatterns = [
path('auth1/', views.Demo1APIView.as_view()),
path('auth2/', views.Demo2APIView.as_view()),
# 自定義權(quán)限
path('auth3/', views.Demo3APIView.as_view()),
# 限流
path('auth4/', views.Demo4APIView.as_view()),
# 過(guò)濾
path('data5/', views.Demo5APIView.as_view()),
# 排序
path('data6/', views.Demo6APIView.as_view()),
]
opt下的views.py
# 排序 from rest_framework.filters import OrderingFilter class Demo6APIView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer filter_backends = [DjangoFilterBackend, OrderingFilter] # 局部配置會(huì)覆蓋全局配置 filter_fields = ['id', "sex"] ordering_fields = ['id', "age"]
6. 分頁(yè)P(yáng)agination
REST framework提供了分頁(yè)的支持。
我們可以在配置文件中設(shè)置全局的分頁(yè)方式,如:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100 # 每頁(yè)數(shù)目
}
也可通過(guò)自定義Pagination類(lèi),來(lái)為視圖添加不同分頁(yè)行為。在視圖中通過(guò)pagination_clas屬性來(lái)指明。
opt下的urls.py
urlpatterns = [
path('auth1/', views.Demo1APIView.as_view()),
path('auth2/', views.Demo2APIView.as_view()),
# 自定義權(quán)限
path('auth3/', views.Demo3APIView.as_view()),
# 限流
path('auth4/', views.Demo4APIView.as_view()),
# 過(guò)濾
path('data5/', views.Demo5APIView.as_view()),
# 排序
path('data6/', views.Demo6APIView.as_view()),
# 分頁(yè)
path('data7/', views.Demo7APIView.as_view()),
]
opt下的views.py
# 分頁(yè) from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination """1. 自定義分頁(yè)器,定制分頁(yè)的相關(guān)配置""" """ # 頁(yè)碼分頁(yè) PageNumberPagination 前端訪問(wèn)形式:GET http://127.0.0.1:8000/opt/data7/?page=4 page=1 limit 0,10 page=2 limit 10,20 # 偏移量分頁(yè) LimitOffsetPagination 前端訪問(wèn)形式:GET http://127.0.0.1:8000/opt/data7/?start=4&size=3 start=0 limit 0,10 start=10 limit 10,10 start=20 limit 20,10 """ class StandardPageNumberPagination(PageNumberPagination): """分頁(yè)相關(guān)配置""" page_query_param = "page" # 設(shè)置分頁(yè)頁(yè)碼關(guān)鍵字名 page_size = 3 # 設(shè)置每頁(yè)顯示數(shù)據(jù)條數(shù) page_size_query_param = "size" # 設(shè)置指定每頁(yè)大小的關(guān)鍵字名 max_page_size = 5 # 設(shè)置每頁(yè)顯示最大值 class StandardLimitOffsetPagination(LimitOffsetPagination): default_limit = 2 # 默認(rèn)限制,默認(rèn)值與PAGE_SIZE設(shè)置一致 limit_query_param = "size" # limit參數(shù)名 offset_query_param = "start" # offset參數(shù)名 max_limit = 5 # 最大limit限制 class Demo7APIView(ListAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer # 分頁(yè) # 頁(yè)碼分頁(yè)類(lèi) pagination_class = StandardPageNumberPagination # 偏移量分頁(yè)類(lèi) # pagination_class = StandardLimitOffsetPagination
注意:如果在視圖內(nèi)關(guān)閉分頁(yè)功能,只需在視圖內(nèi)設(shè)置
pagination_class = None
到此這篇關(guān)于Django DRF路由與擴(kuò)展功能的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Django DRF路由與擴(kuò)展內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)的遠(yuǎn)程登錄windows系統(tǒng)功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)的遠(yuǎn)程登錄windows系統(tǒng)功能,結(jié)合實(shí)例形式分析了Python基于wmi模塊的遠(yuǎn)程連接與進(jìn)程操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-06-06
Python人工智能實(shí)戰(zhàn)之以圖搜圖的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了如何基于vgg網(wǎng)絡(luò)和Keras深度學(xué)習(xí)框架實(shí)現(xiàn)以圖搜圖功能。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2022-05-05
Python類(lèi)的基礎(chǔ)入門(mén)知識(shí)
關(guān)于類(lèi)的定義2008-11-11
Python實(shí)現(xiàn)判斷一個(gè)字符串是否包含子串的方法總結(jié)
這篇文章主要介紹了Python實(shí)現(xiàn)判斷一個(gè)字符串是否包含子串的方法,結(jié)合實(shí)例形式總結(jié)分析了四種比較常用的字符串子串判定方法,需要的朋友可以參考下2017-11-11

