一篇文章带你了解django-rest-framework

django-rest-framework

restful

api部署在专有域名下

路径不能有动词

版本在地址后拼接,或在header中

不同请求不同方式

通过参数过滤

状态码, 200,201,204,401,403,404,500

使用json返回数据

安装

pip install djangorestframework

使用

https://q1mi.github.io/Django-REST-framework-documentation/

settings

INSTALLED_APPS = [
  'rest_framework',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (  # 身份验证
        'rest_framework.authentication.BasicAuthentication',  # 需要登录,用于测试,弹出框用于登录
        'rest_framework.authentication.SessionAuthentication',  # session登录
    ),
    'DEFAULT_PERMISSION_CLASSES': (  # 权限验证(全局)
        'rest_framework.permissions.IsAuthenticated',  # 普通用户
        'rest_framework.permissions.AllowAny',  # 所有用户
        'rest_framework.permissions.IsAdminUser', # 管理员
    ),
    'DEFAULT_THROTTLE_CLASSES': (  # 限流用户
        'rest_framework.throttling.AnonRateThrottle',  # 限制未授权用户
        'rest_framework.throttling.UserRateThrottle'  # 限制认证用户
    ),
    'DEFAULT_THROTTLE_RATES': {  # 限流量
        'anon': '100/day',  # 未授权用户访问限制次数, 1/minute
        'user': '1000/day',  # 认证用户访问限制次数
        'my_throttle': '10/minute',  # 自定义限制, 通用视图中用throttle_scope添加限制
    },
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',  # 默认分页器
    'PAGE_SIZE': 100,  # 默认每页数量,使用全局的时候无法用过参数修改每页数量
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
}

url

from rest_framework.routers import DefaultRouter,SimpleRouter
urlpatterns = [
  path('api/', include('rest_framework.urls'))
]
job_router = SimpleRouter()  # 创建router
job_router.register(prefix='manager/job', viewset=ModelViewSetApi, basename='job')  # 注册view视图, prefix基本路径, viewset注册的视图, basename url的name的基本部分' basename+urlname
访问时根据  manager/job/-> list post , manager/job/pk  put delete get,  默认没有自定义方法
还可通过加  .json 返回json格式的数据

urlpatterns += job_router.urls  # 添加路由
print(urlpatterns)

views

django通用视图

from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from .models import Jobs
from rest_framework import viewsets
from django.views.generic import ListView
from .serializer import JobSerializer, LabelSerializer  # 从序列化器文件引入序列化器

class Index(ListView):  # 通用视图,具体看django笔记
    template_name = 'job/index.html'
    paginate_by = 10
    job_serializer = JobSerializer(instance=Jobs.objects.all(), many=True)  # 序列化

    model = Jobs

    # def get_queryset(self):
    #     return Jobs.objects.all()

    # def get(self, request, *args, **kwargs):  # 重写get参数
    #
    #     print(self.job_serializer)
    #     return JsonResponse(self.job_serializer.data, safe=False)

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data()
        context['another'] = '其他的参数'
        context['page_range'] = pages_divider(context['page_obj'].number, context['paginator'].page_range)
        # print(context)
"""
        {'paginator': None, 'page_obj': None, 'is_paginated': False, 'object_list': <queryset [<jobs: jobs object (00018e71bca90ceacb1bacde563bd236)>]>, 'jobs_list': <queryset [<jobs: jobs object (00018e71bca90ceacb1bacde563bd236)>]>, 'view': <job.views.index object at 0x0000022dcd9883d0>, 'another': '&#x5176;&#x4ED6;&#x7684;&#x53C2;&#x6570;'}
"""
        return context

    def post(self, request, *args, **kwargs):
        data = request.POST.get('data')
        print(data)
        d = JobSerializer(data=data)  # &#x53CD;&#x5E8F;&#x5217;&#x5316;, &#x521B;&#x5EFA;&#x6570;&#x636E;&#x7684;&#x5E8F;&#x5217;&#x5316;&#x5668;
        if d.is_valid(raise_exception=True):  # &#x6570;&#x636E;&#x683C;&#x5F0F;&#x68C0;&#x9A8C;
          print(d)
          d.save()  # &#x4FDD;&#x5B58;&#x6570;&#x636E;
        return HttpResponse(data)

def pages_divider(page, page_range, perpage=5):  # &#x83B7;&#x53D6;&#x9875;&#x7801;&#x8303;&#x56F4;
    page = int(page)
    if len(page_range) < perpage:
        return page_range
    if perpage / 2 - int(perpage / 2) == 0.5:
        start = page - int(perpage / 2)
        end = page + int(perpage / 2)
        if start < 1:
            start = 1
            end = perpage
        if end > page_range[-1]:
            end = page_range[-1]
            start = end - perpage
        return range(start, end + 1)
    else:
        start = page - int(perpage / 2) + 1
        end = page + int(perpage / 2)
        if start < 1:
            start = 1
            end = perpage
        if end > page_range[-1]:
            end = page_range[-1]
            start = end - perpage + 1
        return range(start, end + 1)
</job.views.index></queryset></queryset>

APIView(一级视图)

from rest_framework.views import APIView # 基本视图
from rest_framework.response import Response  # DRF响应
from rest_framework import status  # DRF状态码

class IndexApi(APIView):  # 使用DRF的类视图
    def get(self, request):  # get方法接口
        d = request.query_params  # 获取get参数
        page = request.query_params['page']

        return Response(data={'d': 1}, status=status.HTTP_200_OK)  # 使用DRF的响应,及状态码

    def post(self, request):  # post方法接口
        d = request.data  # 获取表单信息
        return Response({'d': 1})

class DetailApi(APIView):
    def get(self, request):
        id_job = request.query_params['id']
        job = Jobs.objects.get(id=id_job)  # 获取要展示model
        s_job = JobModelSerializer(instance=job, many=False)
        return Response(data=s_job.data, status=status.HTTP_200_OK)

    def post(self, request):
        data = request.data
        s = JobModelSerializer(data=data)  # 用表单数据创建序列化实例
        if s.is_valid(raise_exception=True):  # 验证数据格式
            s.save()  # 验证通过保存数据
            return Response(data)
        raise serializers.ValidationError('error')  # 不通过报错

    def put(self, request):  # put方法接口
        data = request.data
        job = Jobs.objects.get(id=data['id'])  # 获取要更新的model
        s = JobModelSerializer(instance=job, data=data)  # 更新数据的序列化器
        if s.is_valid(raise_exception=True):
            s.save()
            return Response(data)
        raise serializers.ValidationError('error')
    def delete(self, request):  # delete方法接口
        job = Jobs.objects.get(id=request.query_params['id']).delete()
        return Response(1, status=200)

Generic二级视图

三个属性三个方法 queryset,serializer_class,lookup_field及pagination_class(分页器)

from rest_framework.generics import GenericAPIView  # Generic视图
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin
from rest_framework.response import Response
from rest_framework import status

class GenericListApi(GenericAPIView):  # 二级视图-列表
    template_name = 'job/index.html'
    queryset = Jobs.objects.all()  # 通用数据集,必须用queryset
    serializer_class = JobModelSerializer  # 通用序列化器,必须用serializer_class
    class Pager(PageNumberPagination):  # 创建自定义DRF分页器, 也可以在settings直接写全局分页配置, 继承GenericAPIView的类才能使用
        max_page_size = 10  # 每页最大显示数
        page_size = 5  # 默认每页数量
        page_query_param = 'page'  # 页码参数名
        page_size_query_param = 'page_size'

    pagination_class = Pager

    def get(self, request, page):
        queryset= self.get_queryset()  # 获取数据用self.get_queryset()
        paginate_queryset = self.paginate_queryset(self.filter_queryset(queryset))  # 获取分页后的数据
        serializer = self.get_serializer(instance=job, many=True)  # 获取序列化器用, self.get_serializer(instance=job,
        # many=True)
        return Response(data=serializer.data, status=status.HTTP_200_OK)
        return render(request, self.template_name, {'data': paginate_queryset})  3 也可以使用django的响应
    def post(self,request):
        serializer = self.get_serizlizer(data=request.data, many=True)
        if serizlizer.is_valued():
            serizlizer.save()
            return Response(1)
        raise serializers.ValidationError('error')

class GenericDetailApi(GenericAPIView):  # 二级视图-详情
    queryset = Jobs.objects.all()  # 一般都是固定的 模型的all, 想要展示的数据的所有
    serializer_class = JobModelSerializer  # 数据对应的序列化器
    lookup_field = 'pk'  # 主键参数名(默认pk), 使用get_object方法使用的get参数

    # lookup_url_kwarg =

    def get(self, request, pk):
        job = self.get_object()  # 通过lookup_field, 从queryset中get想要的数据
        serializer = self.get_serializer(instance=job)  # 获取序列化器
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def put(self, request, pk):
        job = self.get_object()  # 会自动使用lookup_field及传入的值get对应model
        serializer = self.get_serializer(instance=job, data=request.data)
        return Response(data=serializer.data, status=status.HTTP_200_OK)

    def delete(self, pk):
        job = self.get_object()
        job.delete()
        return Response(data='success', status=status.HTTP_203_NON_AUTHORITATIVE_INFORMATION)

Generic+Minin

from rest_framework.generics import GenericAPIView  # Generic视图
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin
from rest_framework.response import Response
from rest_framework import status

class MixinListApi(GenericAPIView, ListModelMixin, CreateModelMixin):  # Mixin, 通用的增删改查
    queryset = Jobs.objects.all()[:200]
    serializer_class = JobModelSerializer
    paginate_by = 20  # 分页数量
    page_kwarg = 'page'  # 页码参数

    def get(self, request):  # 获取
        return self.list(request)  # 这里的方法就是继承的ListModelMixin 创建的方法, 获取数据

    def post(self, request):  # 创建
        return self.create(request)  # CreateModelMixin的方法, 创建model

class MixinDetailApi(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):  #
    queryset = Jobs.objects.all()
    serializer_class = JobModelSerializer
    lookup_field = 'pk'  # 主键参数名(默认pk)

    lookup_url_kwarg = 'pk'

    def get(self, request, pk):
        return self.retrieve(request)

    def put(self, request, pk):  # 修改
        return self.update(request)  # 修改pk对应model

    def delete(self, request, pk):   # 删除
        return self.delete(request)  # DestroyModelMixin的方法, 删除pk对应model

视图集

     views.ModelViewSetApi.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
from rest_framework.viewsets import ViewSet, ModelViewSet, ReadOnlyModelViewSet
from django.shortcuts import get_object_or_404

视图集>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.

"""
ViewSet 路由映射  , path('api', viewset.as_view({'get':'list','post':'create'}),)

urlpatterns = [
    path('ModelViewSetApi/', views.ModelViewSetApi.as_view({'get': 'list', 'post': 'create'})),
    path('ModelViewSetApi//', views.ModelViewSetApi.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),

]

GenericViewSet  路由映射 三个属性三个方法 queryset,serializer_class,lookup_field, get_queryset, get_serizlizer, get_object
ModelViewSet 增删改查,三个属性三个方法
ReadOnlyModelViewSet  # 获取单个,获取列表,三个属性三个方法
"""

视图集原理
class ViewSetApi(ViewSet):  # 提供了通过as_view映射请求方式到本身的方法(可以映射自定义方法),viewset.as_view({'get':'list','post':'create'}
    paginate_by = 10
    page_kwarg = 'page'  # 页码参数

    def list(self, request):
        queryset = Jobs.objects.all()
        p = Paginator(queryset, 10)
        serializer = JobModelSerializer(instance=p.page(request.query_params['page']), many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def retrieve(self, request, pk):
        queryset = Jobs.objects.all()
        job = get_object_or_404(queryset, pk=pk)
        serializer = JobModelSerializer(instance=job)
        return Response(serializer.data, status=status.HTTP_200_OK)

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination

分页器
class Pager(PageNumberPagination):  # 创建自定义DRF分页器, 也可以在settings直接写全局分页配置, 继承GenericAPIView的类才能使用
    max_page_size = 10  # 每页最大显示数
    page_query_param = 'page'  # 页码参数名
    page_size_query_param = 'page_size'  # 页码数据量参数名

只读视图集
class ReadOnlyModelViewSetApi(ReadOnlyModelViewSet):  # 读取单个和列表,及请求映射
    queryset = Jobs.objects.all()
    serializer_class = JobModelSerializer
    lookup_field = 'pk'
    pagination_class = Pager  # 使用自定义分页器,请求时必须写page(page_query_param)和page_size(page_size_query_param)这两个参数, 继承GenericAPIView的类才能使用

from rest_framework.decorators import action
通用视图集
class ModelViewSetApi(ModelViewSet):  # 通用增删改查及请求方式映射
    queryset = Jobs.objects.all()
    serializer_class = JobModelSerializer
    lookup_field = 'pk'
    pagination_class = Pager  # 使用自定义分页器,请求时必须写page(page_query_param)和page_size(page_size_query_param)这两个参数, 继承GenericAPIView的类才能使用

    permission_class = [rest_framework.permissions.AllowAny]  # 局部权限验证
    authentication_classes = [IsAuthenticated]  # 局部身份验证
    throttle_classes = [AnonRateThrottle, UserRateThrottle]  # 局部限流
    throttle_scope = "my_throttle"  # 可选限流

    # 使DRF自动创建路由, methods允许访问的方式, url_path路径, basename(router中)+url_name = name(path中), detail是否需要传入lookup_field
    @action(methods=['put'], detail=True, url_path='change', url_name='change')
    def update_job_requires(self,request, pk):  # 局部更新数据  prefix//url_path
        job = self.get_object()
        serializer = self.get_serializer(instance=job, data=request.data, partial=True)  # partial修改部分数据
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(request.data)

自动生成路由

from rest_framework.routers import DefaultRouter,SimpleRouter
urlpatterns = []

job_router = DefaultRouter()  # 创建router
job_router.register(prefix='job', viewset=ModelViewSetApi, basename='job')  # 注册view视图, prefix基本路径, viewset注册的视图, basename url的name的基本部分' basename+urlname
访问时根据  manager/job/-> list post , manager/job/pk  put delete get,  默认不创建自定义方法的路由, 需要加action装饰器
还可通过加  .json 返回json格式的数据

urlpatterns += job_router.urls  # 添加路由

视图集自动生成的url (DefaultRouter)

,
[a-z0-9]+)/?$' [name='jobs-list']>,
[^/.]+)/$' [name='jobs-detail']>,
[^/.]+)\.(?P[a-z0-9]+)/?$' [name='jobs-detail']>,
[^/.]+)/change/$' [name='jobs-c']>,
[^/.]+)/change\.(?P[a-z0-9]+)/?$' [name='jobs-c']>,
,
[a-z0-9]+)/?$' [name='api-root']>]

视图集自动生成的url (SimpleRouter)

,
[^/.]+)/$' [name='jobs-detail']>,
[^/.]+)/change/$' [name='jobs-change']>]  # 自定义方法的路由

serializer

标准序列化器

from rest_framework import serializers
import datetime
from .models import Jobs

class JobSerializer(serializers.Serializer):  # &#x521B;&#x5EFA;&#x5E8F;&#x5217;&#x5316;&#x7C7B;
    def create(self, validated_data):  # &#x4FDD;&#x5B58;&#x6570;&#x636E;
        Jobs.objects.create(**validated_data)
        return 1

    def update(self, instance, validated_data):  # &#x66F4;&#x65B0;&#x6570;&#x636E;
        for k, v in validated_data.items():
            if hasattr(instance, k):  # &#x5224;&#x65AD;&#x662F;&#x5426;&#x6709;&#x5C5E;&#x6027;
                setattr(instance, k, v)  # &#x8BBE;&#x7F6E;&#x5C5E;&#x6027;&#x503C;
        instance.save()
        return 1

    id = serializers.PrimaryKeyRelatedField(read_only=True)  # &#x9009;&#x62E9;&#x60F3;&#x8981;&#x5C55;&#x793A;&#x7684;&#x5B57;&#x6BB5;,&#x5B57;&#x6BB5;&#x540D;,&#x5B57;&#x6BB5;&#x7C7B;&#x578B;&#x548C;model&#x7684;&#x5B57;&#x6BB5;&#x4E00;&#x6837;, &#x4E3B;&#x952E;`&#x5916;&#x952E;
    name = serializers.CharField(max_length=128)
    company = serializers.CharField(max_length=200)
    salary = serializers.CharField(max_length=64)
    requires = serializers.CharField()
    issue = serializers.DateTimeField()
    education = serializers.CharField(max_length=64, allow_null=True, allow_blank=True)
    position = serializers.CharField(max_length=128, allow_null=True)
    platform = serializers.CharField(max_length=20)
    get_data = serializers.DateTimeField(default=datetime.datetime.now())
    # label_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)  # &#x5173;&#x8054;&#x4ED6;&#x7684;&#x7684;&#x5BF9;&#x8C61;, &#x540D;&#x5B57;&#x5C31;&#x662F;related_name&#x7684;&#x503C;
    label_set = serializers.StringRelatedField(read_only=True,
                                               many=True)  # &#x5173;&#x8054;&#x4ED6;&#x7684;&#x7684;&#x5BF9;&#x8C61;&#x7684;__str__(&#x8981;&#x6709;__str__&#x65B9;&#x6CD5;), &#x540D;&#x5B57;&#x5C31;&#x662F;related_name&#x7684;&#x503C;

    @staticmethod  # &#x7528;&#x4E0D;&#x7740;self&#x6216;cls&#x7684;&#x8BDD;&#x53EF;&#x4EE5;&#x7528;&#x9759;&#x6001;&#x65B9;&#x6CD5;
    def validate_name(value):  # &#x5355;&#x5B57;&#x6BB5;&#x6821;&#x9A8C;
        if '?' in value:
            raise serializers.ValidationError("&#x4E0D;&#x80FD;&#x5305;&#x542B;&#x7279;&#x6B8A;&#x7B26;&#x53F7;")
        return value

    @staticmethod
    def validate(*args):  # &#x591A;&#x5B57;&#x6BB5;&#x6821;&#x9A8C;, &#x76F4;&#x63A5;&#x7528;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x5C31;&#x884C;, &#x4E0D;&#x7528;&#x52A0;*&#x548C;&#x7D22;&#x5F15;&#x8BBF;&#x95EE;
        # print(args[0])
        # print(args)
        if args[0]['issue'] > args[0]['get_data']:
            raise serializers.ValidationError("&#x53D1;&#x5E03;&#x65F6;&#x95F4;&#x5927;&#x4E8E;&#x722C;&#x53D6;&#x65F6;&#x95F4;")
        return args[0]
    # def validate(data):  # &#x591A;&#x5B57;&#x6BB5;&#x6821;&#x9A8C;, &#x76F4;&#x63A5;&#x7528;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x5C31;&#x884C;, &#x4E0D;&#x7528;&#x52A0;*&#x548C;&#x7D22;&#x5F15;&#x8BBF;&#x95EE;
    #     if data['issue'] > data['get_data']:
    #         raise serializers.ValidationError("&#x53D1;&#x5E03;&#x65F6;&#x95F4;&#x5927;&#x4E8E;&#x722C;&#x53D6;&#x65F6;&#x95F4;")
    #     return data

class LabelSerializer(serializers.Serializer):
    def create(self, validated_data):
        pass

    def update(self, instance, validated_data):
        pass

    job = serializers.PrimaryKeyRelatedField(read_only=True)  # &#x663E;&#x793A;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x7684;id
    # job = serializers.StringRelatedField(read_only=True)  # &#x663E;&#x793A;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x7684;__str__&#x7684;&#x4FE1;&#x606F;
    # job = JobSerializer()  # &#x663E;&#x793A;&#x5173;&#x8054;&#x5BF9;&#x8C61;&#x7684;&#x5E8F;&#x5217;&#x5316;&#x5668;&#x6240;&#x6709;&#x5B57;&#x6BB5;&#x7684;&#x4FE1;&#x606F;
    value = serializers.CharField(max_length=64)

模型序列化器

class JobModelSerializer(serializers.ModelSerializer):  # 模型序列化器, 自动生成对应的序列化字段
"""
    内置了create,update方法
"""
    token = serializers.CharField(max_length=100, write_only=True)  # 添加额外的字段, write_only只反序列化不显示(序列化)

    class Meta:
        model = Jobs  # 自动生成所有序列化字段
        fields = "__all__"  # all生成所有字段, ['name','issue','salary'] 列表或元组,选择部分字段
        read_only_fields = ['id']  # 设置只读字段, 可以显示, 修改无效
        extra_kwargs = {

            'name': {  # 修改字段参数, 默认的字段参数不满足时可以在这额外添加或修改
                'max_length': 200
            },
            'position': {
                'max_length': 50
            }
        }

字段选项及字段类型


"""
字段选项
LIST_SERIALIZER_KWARGS = (
    'read_only', 'write_only', 'required', 'default', 'initial', 'source',
    'label', 'help_text', 'style', 'error_messages', 'allow_empty',
    'instance', 'data', 'partial', 'context', 'allow_null',
    'max_length', 'min_length'
)
read_only  设置只读字段, 修改无效
write_only

反序列化时, 设置的default read_only=True required=False 不需要传参

字段类型(序列化器对应的model字段类型)
serializer_field_mapping = {
    models.AutoField: IntegerField,
    models.BigIntegerField: IntegerField,
    models.BooleanField: BooleanField,
    models.CharField: CharField,
    models.CommaSeparatedIntegerField: CharField,
    models.DateField: DateField,
    models.DateTimeField: DateTimeField,
    models.DecimalField: DecimalField,
    models.DurationField: DurationField,
    models.EmailField: EmailField,
    models.Field: ModelField,
    models.FileField: FileField,
    models.FloatField: FloatField,
    models.ImageField: ImageField,
    models.IntegerField: IntegerField,
    models.NullBooleanField: BooleanField,
    models.PositiveIntegerField: IntegerField,
    models.PositiveSmallIntegerField: IntegerField,
    models.SlugField: SlugField,
    models.SmallIntegerField: IntegerField,
    models.TextField: CharField,
    models.TimeField: TimeField,
    models.URLField: URLField,
    models.UUIDField: UUIDField,
    models.GenericIPAddressField: IPAddressField,
    models.FilePathField: FilePathField,
}

"""

Original: https://blog.csdn.net/weixin_44811751/article/details/123409781
Author: 殊毅
Title: 一篇文章带你了解django-rest-framework

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/735492/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【Matplotlib】Matplotlib绘图样式索引(含形状、颜色、标签位置)

    文章目录 Matplotlib绘图样式 * 1.创建一个(或多个)图表 – 创建一个图表 创建多个图表 2. Axis标签位置 3.基本绘图样式 4.线条样式 5.标记…

    Python 2023年9月4日
    058
  • pandas-Dataframe(取数)

    DataFrame DataFrame是什么 DataFrame的常用API DataFrame局部数据的API(取数) * loc 和iloc(重要) – 功能: 区…

    Python 2023年8月16日
    080
  • 行人属性识别数据集总结

    啊哦~你想找的内容离你而去了哦 内容不存在,可能为如下原因导致: ① 内容还在审核中 ② 内容以前存在,但是由于不符合新 的规定而被删除 ③ 内容地址错误 ④ 作者删除了内容。 可…

    Python 2023年11月5日
    036
  • 玩转Python飞机大战项目

    文章目录 前言 一、代码下载及导入项目 二、安装相关依赖组件 * 1.安装pygame 2.安装pyinstaller 三、运行及打包 * 1、运行 2、打包成可执行文件。 总结 …

    Python 2023年9月22日
    054
  • conf文件中如何导入python变量_如何在pytest中设置导入前的配置conftest.py?

    我有myprj项目,文件如下。在$ tree myprj/ myprj/ ├── prj │ ├── init.py │ ├── config.py │ ├── my_logger…

    Python 2023年9月12日
    058
  • 数据处理小工具:Excel 批量数据文件拆分/整合器…

    需求分析: 现在有一大堆的Excel数据文件,需要根据每个Excel数据文件里面的Sheet批量将数据文件合并成为一个汇总后的Excel数据文件。或者是将一个汇总后的Excel数据…

    Python 2023年11月9日
    044
  • pytest(1): 入门篇

    执行 1.在控制台执行 pytest 2.在控制台指定执行范围a.指定某个模块 pytest test_module.pyb.指定某个目录及其子目录的所有测试文件 pytest t…

    Python 2023年9月14日
    046
  • conda下载源不一致+代理出错+包不一致问题解决方法记录

    文章目录 * – 问题描述 & 解决方法 – + * 问题1:下载源不一致Environment is inconsistent * 问题2:代理出…

    Python 2023年9月8日
    048
  • Python递归的几个经典案例

    当我们碰到诸如需要求阶乘或斐波那契数列的问题时,使用普通的循环往往比较麻烦,但如果我们使用递归时,会简单许多,起到事半功倍的效果。这篇文章主要和大家分享一些和递归有关的经典案例,结…

    Python 2023年11月1日
    050
  • 基于 Python 的 M-K(Mann-Kendall)突变检验 的简单实现

    M-K(Mann-Kendall)法是一种气候诊断与预测技术,可以判断气候序列中是否存在气候突变,如果存在,可确定出突变发生的时间。Mann-Kendall检验法也经常用于气候变化…

    Python 2023年8月1日
    0171
  • 如何进行项目开发?

    企业的web项目类型 商城 1.1 B2C 直销商城 商家与会员直接交易 ( Business To Customer ) 1.2 B2B 批发商城 商家与商家直接交易 1.3 B…

    Python 2023年6月10日
    080
  • python中的super是什么?

    python中的super,名为超类,可以简单的理解为执行父类的__init__函数。由于在python中不论是一对一的继承,还是一子类继承多个父类,都会涉及到执行的先后顺序的问题…

    Python 2023年11月9日
    035
  • Python 笔记

    Python 由 Guido van Rossum(荷兰 🇳🇱)开发。 Python 是一门解释型语言、动态类型(弱类型)语言。 Python 的名字来源于 Monty Pytho…

    Python 2023年6月9日
    052
  • 【Hadoop】5、集群运行

    步骤一、NameNode 格式化 步骤二、启动 NameNode 步骤三、启动 SecondaryNameNode 步骤四、slave 启动 DataNode 步骤五、查看 HDF…

    Python 2023年6月3日
    092
  • 通达信全市场数据导入指南—基于股票量化分析工具V2.0!

    今天是除夕夜,祝大家春节快乐!阖家欢乐!万事如意!骑牛冲天! 不少小伙伴准备趁着春节假期,好好结合书本消化下股票量化分析工具V2.0代码。 这样可以把自己的分析思路量化到工具中,来…

    Python 2023年8月8日
    066
  • python——正则表达式(re模块)详解

    在Python中需要通过正则表达式对字符串进⾏匹配的时候,可以使⽤⼀个python自带的模块,名字为re。 正则表达式的大致匹配过程是:1.依次拿出表达式和文本中的字符比较,2.如…

    Python 2023年8月1日
    064
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球