DRF的接口使用

2024-04-29 12:04
文章标签 接口 使用 drf

本文主要是介绍DRF的接口使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【一】如何看cbv源码

​ 需要看源码。 在看python源码的时候 一定要时刻提醒自己面向对象属性方法查找顺序

  • 先从对象自己找
  • 再去产生对象的类里面找
  • 之后再去父类找

总结: 看源码只要看到了self点一个东西 一定要问你自己当前这个self到底是谁

cbv的源码 : 突破口在urls.py

from django.contrib import admin
from django.urls import path,re_path
from app01 import viewsurlpatterns = [# CBV源码re_path('r^login/',views.MyLogin.as_view()),
]
# re_path('r^login/',views.view),  这里CBV跟FBV 一模一样
# '''这里可以看出CBV跟FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址'''# 函数名/方法名  加括号优先级最高
# 这里我们可以假设一下as_view()要么是被@staticmethod修饰的静态方法要么是被@classmethod修饰的类的方法  ✓@classonlymethoddef as_view(cls, **initkwargs):"""Main entry point for a request-response process."""for key in initkwargs:pass
# cls 就是我们自己写的类  MyCBV
def view(request, *args, **kwargs):# cls 就是我们自己写的类# self = MyLogin(**initkwargs)  产生一个我们自己写的类的对象self = cls(**initkwargs)self.setup(request, *args, **kwargs)
'''需要看源码。 在看python源码的时候  一定要时刻提醒自己面向对象属性方法查找顺序- 先从对象自己找- 再去产生对象的类里面找- 之后再去父类找总结: 看源码只要看到了self点一个东西  一定要问你自己当前这个self到底是谁
'''
# CBV的精华
def dispatch(self, request, *args, **kwargs):# Try to dispatch to the right method; if a method doesn't exist,# defer to the error handler. Also defer to the error handler if the# request method isn't on the approved list.# 获取的当前请求的小写格式  如何对比当前请求方式是否合法# get请求为例子# post请求if request.method.lower() in self.http_method_names:handler = getattr(self, request.method.lower(), self.http_method_not_allowed)'''反射:通过字符串来操作对象的数学或者方法handler = getattr(自己写的类产生的对象,'get',当找不到get数学或者方法的时候机会用到第三个参数)handler = 我们自己写的类里面的get方法'''else:handler = self.http_method_not_allowedreturn handler(request, *args, **kwargs)'''自动调用get方法'''

1

在这里插入图片描述

2

在这里插入图片描述

3

在这里插入图片描述

4

image-20240229230949408

cbv源码的执行流程

​ CBV(Class-Based Views)是一种处理HTTP请求的方式,相比FBV(Function-Based Views)更加灵活和易于维护。CBV源码的执行流程大致如下:

  1. URL匹配和路由分发:当一个HTTP请求到达Django应用时,Django会根据URL配置文件中的路由规则将请求分发到相应的视图函数。
  2. 视图函数调用:对于CBV,路由规则通常会指向一个继承自Django提供的特定类的视图类,而不是一个普通的函数。当请求到达相应的视图类时,Django会实例化该类,并调用其中的dispatch方法。
  3. dispatch方法dispatch方法是CBV执行的入口。在dispatch方法中,Django会根据请求的HTTP方法(GET、POST、PUT等)调用相应的处理方法,例如getpostput等。
  4. 请求处理方法:在视图类中,通常会定义一系列处理请求的方法,如getpost等。这些方法接收请求对象作为参数,并根据请求的具体情况执行相应的逻辑。
  5. Mixin扩展:CBV可以通过Mixin类来扩展功能。Mixin类是一种特殊的类,可以通过多重继承的方式将其添加到视图类中,从而为视图类提供额外的功能,例如身份验证、缓存等。
  6. 模板渲染:在视图类中,可以通过调用render方法来渲染模板并生成HTML响应。render方法接收模板名称和上下文数据作为参数,并返回渲染后的HTML内容。
  7. 响应返回:最后,视图类会生成一个HTTP响应对象,并将其返回给客户端。这个响应对象通常包含HTTP状态码、响应头和响应体等信息。

​ 总的来说,CBV的执行流程可以简单概括为:URL匹配和路由分发 → 视图函数调用 → dispatch方法 → 请求处理方法 → 模板渲染 → 响应返回。

【二】在视图层View编写5个接口

  • 什么是csrf

    • CSRF 就是攻击者利用一个用户已经登录的身份,在用户不知情的情况下对另一个网站或应用发起恶意请求。
  • 防止的措施

    • CSRF Token:在用户登录时生成一个随机的 token,并将其嵌入到表单或请求的参数中,在后续的请求中验证这个 token 的有效性,确保请求来源合法。
    • SameSite Cookie 属性:设置 Cookie 的 SameSite 属性,限制 Cookie 只能在相同站点请求中发送,防止跨站点请求。
    • 验证 Referer:验证请求的 Referer 头部,确保请求来源合法。
    • 双重提交 Cookie:将一个随机值存储在 Cookie 中,并在表单中将这个值作为参数发送,在服务器端验证这个值与 Cookie 中的值是否匹配。
基于View编写5个接口--csrf-序列化自己做--》JsonResponse多条--for 字典--》追加到列表中单体新增修改删除 

【0】前提条件

​ 继承View编写修改接口,让他使用json格式提交数据,修改成功
​ 写一个装饰器,装饰视图函数FBV,使得request有data属性,无论哪种编码和请求方式,都是字典

【1】准备Book的数据

  • 创建一个名为Book表跟book的数据库

  • 启动MySQL

net start mysql
  • 输入密码的两种方式
---mysql -u root -P 3306 -p
--- mysql -u root -p
********************

image-20240411224416105

  • 在model.py文件中创建数据库
from django.db import models# Create your models here.
class Book(models.Model):name = models.CharField(max_length=88)price = models.IntegerField()publish = models.CharField(max_length=66)
  • 前提是先在settings.py文件中先定义
DATABASES = {'default': {# 数据库引擎选择使用MySQL'ENGINE': 'django.db.backends.mysql',# 指定数据库名字,需提前创建'NAME': 'books',# 指定数据库用户名'USER': 'root',# 指定数据库用户密码'PASSWORD': '123123',# 指定数据库连接IP'HOST': '127.0.0.1',# 指定数据库端口'PORT': 3306,# 指定数据库默认编码集(可选)'CHARSET': 'utf8mb4',}
}
  • 数据迁移
''' python manage.py makemigrationspython manage.py migrate '''

【2】在views

  • 第一步

from django.http import JsonResponse
import re
import json
from urllib.parse import unquote
# Create your views here.
from django.utils.decorators import method_decorator
from django.views import View
from .models import Book
class BookView(View):def get(self, request):res_list = Book.objects.all()data_list = []for res in res_list:data_list.append({'name': res.name, 'price': res.price, 'publish': res.publish})return JsonResponse({'code': 100, 'msg': '查询成功', 'results': data_list})def post(self, request):# 前端无论以什么编码格式--》提交到后端你的数据,都会被解析到 request.data 中,是个字典# 如果是urlencoded或form-data编码--》不能直接这样写,要写成如下data = request.POSTbook = Book.objects.create(name=data.get('name'), price=data.get('price'), publish=data.get('publish'))return JsonResponse({'code': 100, 'msg': '新增成功'})# 如果是json格式编码,下面没问题# Book.objects.create(**request.data)print(request.POST)print(request.data)# 本质原因是?''' APIView帮咱们呢---》看POST中有没有数据,如果有,直接赋值给data,如果没有,他去body中转成字典再给datajson格式:POST没有东西 QueryDictdata有数据  dicturlencoded或form-dataPOST有东西 QueryDictdata有数据  QueryDict'''return JsonResponse({'code': 100, 'msg': '新增成功'})# 127.0.0.1:8000/app01/books/1
@method_decorator(outter,'post')
# @method_decorator(outter,'delete')
class BookDetailView(View):def get(self, request, pk):res = Book.objects.filter(pk=pk).first()# 加个逻辑判断return JsonResponse({'code': 100, 'msg': '查询成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})def delete(self, request, pk):try:# 尝试从数据库中获取指定主键的对象book = Book.objects.get(pk=pk)except Book.DoesNotExist:# 如果对象不存在,则返回相应的 JSON 响应return JsonResponse({'code': 200, 'msg': '没有数据!!!'})# 如果对象存在,则删除它book.delete()# 返回删除成功的 JSON 响应return JsonResponse({'code': 100, 'msg': '删除成功'})def put(self, request, pk):# 跟post新增数据一样,编码格式不是json就会报错print(request.body)data = request.bodyres_data = json.loads(data)print(res_data)name = res_data.get('name')price = res_data.get('price')publish = res_data.get('publish')Book.objects.filter(pk=pk).update(name=name,price=price,publish=publish)return JsonResponse({'code': 100, 'msg': '修改成功'})def post(self, request):# body gen body的使用方法# print(request.body)# ta = request.body# da = json.loads(ta)name = request.POST.get('name')price = request.POST.get('price')publish = request.POST.get('publish')# 保存任务到数据库res = Book.objects.create(name=name,price=price,publish=publish,)return JsonResponse({'code': 100, 'msg': '添加成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})
  • 第二步

​ 添加一个装饰器才能实现无论哪种编码和请求方式,都是字典

def outter(func):def inner(*args, **kwargs):data = Nonerequest = args[0]content_type = request.META.get('CONTENT_TYPE')if 'json' in content_type:data = json.loads(request.body)elif 'urlencoded' in content_type:data = request.body.decode('utf-8')# 将查询字符串拆分为键值对列表body_list = data.split('&')decode = {}for body in body_list:decode[body.split("=")[0]] = unquote(body.split("=")[1])print(decode)# 最终得到的解析后的字典data = decodeelif 'form-data' in content_type:data = request.body.decode('utf8')pattern = r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)'res = re.findall(pattern, string=data)data = {i[0]: i[1] for i in res}request.data = datares = func(*args, **kwargs)return resreturn inner

​ 这个装饰器的内部函数 inner 接收任意数量的位置参数 args 和关键字参数 kwargs,然后提取第一个位置参数(即 HTTP 请求对象)并赋值给 request 变量。接下来,它获取请求的 Content-Type,根据不同的 Content-Type 类型对请求的 body 数据进行解析,并将解析后的数据存储在 data 变量中。

  • 如果 Content-Type 中包含 ‘json’,则将请求的 body 数据解析为 JSON 格式。
  • 如果 Content-Type 中包含 ‘urlencoded’,则将请求的 body 数据解析为 URL 编码格式,并将其拆分为键值对列表,然后使用列表推导式和解码函数 unquote 将每个键值对进行解码,并构建成字典。
  • 如果 Content-Type 中包含 ‘form-data’,则使用正则表达式从 body 数据中提取键值对,并将其存储为字典格式。

第一句代码 data = {i[0]: unquote(i[-1]) for i in [info.split('=') for info in data.split('&')]} 是用来解析 URL 编码格式的数据。具体解释如下:

  • data.split('&'): 这一部分将请求的 body 数据按照 ‘&’ 符号进行拆分,得到一个包含键值对的列表。
  • [info.split('=') for info in data.split('&')]: 这一部分使用列表推导式,对上一步得到的列表中的每个键值对进行拆分,按照 ‘=’ 符号将键值对分成键和值,并构成一个新的列表。
  • {i[0]: unquote(i[-1]) for i in [info.split('=') for info in data.split('&')]}: 这一部分再次使用列表推导式,对拆分后的键值对列表中的每个元素进行处理。其中,i[0] 表示取每个键值对中的键,而 i[-1] 表示取每个键值对中的值。然后使用 unquote 函数对值进行 URL 解码,最终构建成一个字典,键为解码后的键,值为解码后的值。

第二句代码 pattern = r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)' 是用来解析 form-data 格式的数据。具体解释如下:

  • r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)'
    

    : 这是一个正则表达式,用于匹配 form-data 类型的数据。在 form-data 中,每个键值对由两部分组成:名称(name)和值。这个正则表达式的主要作用是匹配 form-data 中的名称和值。

    • Content-Disposition: form-data; name="([^"]+)": 这一部分匹配了 form-data 中的名称,使用了括号捕获组 ([^"]+) 来匹配名称的值,即键。
    • \s*\r\n\s*\r\n: 这一部分匹配了 form-data 中键值对之间的空行,即键值对之间的分隔符。
    • (.*?): 这一部分匹配了 form-data 中的值,使用了非贪婪匹配 .*? 来匹配任意字符,直到下一个分隔符或者结束符。
    • (?=\r\n|--.*?--|\Z): 这一部分是一个前瞻断言,用于确定值的结束位置。它匹配了一个空行 \r\n 或者 form-data 结束符 --.*?-- 或者字符串的结尾 \Z

【3】在urls

先在主路由先实现一个路由分发

from django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),path('Api01/', include('Api01.urls')),
]

子路由

from django.urls import path,include
# BookView、BookDetailView 这个就是我在views.py 定义的类
from Api01.views import BookView,BookDetailView
urlpatterns = [path('books/', BookDetailView.as_view()),path('books/<int:pk>/', BookDetailView.as_view()),]

【4】在postman进行检验

具体其他的自己练

image-20240411231213457

image-20240411230941768

image-20240411231017754

【5】注意事项

​ 在下面的实例来说这里的在Task表的取值就是就是用request.body就是只能使用python中反序列化

​ 因为它返回的是一个字典的形式

'''b'{"task_name":"jian","task_desc":"666"}'
{'task_name': 'jian', 'task_desc': '666'}
<class 'dict'>
Task object (3)
jian '''

例如:

import json# 假设 request.body 就是你提供的字节串
body_bytes = b'{"task_name":"jian","task_desc":"666"}'# 将字节串解析为 Python 字典对象
body_dict = json.loads(body_bytes)# 现在可以访问 body_dict 中的数据了
print(body_dict['task_name'])  # 输出 'jian'
print(body_dict['task_desc'])  # 输出 '666'
def put(self, request, id):try:print(request.body)data = request.bodycalssdatda = json.loads(data)print(calssdatda)print(type(calssdatda))# <class 'dict'>task = Task.objects.get(id=id)print(task)task_name = calssdatda.get('task_name')print(task_name)task_desc = calssdatda.get('task_desc')task_time = time.strftime('%Y-%m-%d')# 更新任务信息task.task_name = task_nametask.task_desc = task_desctask.task_time = task_timetask.save()return JsonResponse({'message': 'Task 更新成功'})except Task.DoesNotExist:return JsonResponse({'error': '未找到数据'}, status=404)
  • 所以我们在使用postman只能用raw中json方法

  • image-20240411233939594

image-20240411232917536

示例二

  • 准备工作

# models.py
from django.db import modelsclass Book(models.Model):name = models.CharField(max_length=88)price = models.IntegerField()publish = models.CharField(max_length=66)
  • View跟APIView这个两个方法区别并不大

# views.py
class BookView(APIView):def get(self, request):res_list = Book.objects.all()data_list = []for res in res_list:data_list.append({'name': res.name, 'price': res.price, 'publish': res.publish})return JsonResponse({'code': 100, 'msg': '查询成功', 'results': data_list})def post(self, request):# 前端无论以什么编码格式--》提交到后端你的数据,都会被解析到 request.data 中,是个字典# 如果是urlencoded或form-data编码--》不能直接这样写,要写成如下data = request.POSTbook = Book.objects.create(name=data.get('name'), price=data.get('price'), publish=data.get('publish'))return JsonResponse({'code': 100, 'msg': '新增成功'})# 如果是json格式编码,下面没问题# Book.objects.create(**request.data)print(request.POST)print(request.data)# 本质原因是?''' APIView帮咱们呢---》看POST中有没有数据,如果有,直接赋值给data,如果没有,他去body中转成字典再给datajson格式:POST没有东西 QueryDictdata有数据  dicturlencoded或form-dataPOST有东西 QueryDictdata有数据  QueryDict'''return JsonResponse({'code': 100, 'msg': '新增成功'})
  • 这个是我写的装饰器
  • 这个装饰器根据请求的 Content-Type 头部信息来判断请求发送的数据类型,然后将数据解析为相应的格式,并存储在请求对象的 data 属性中。解析的数据包括 JSON 格式、urlencoded 格式和 form-data 格式。
  • 白话文就是可以让我随便使用JSON格式、urlencoded格式和form-data格式。
def outter(func):def inner(*args, **kwargs):data = Nonerequest = args[0]content_type = request.META.get('CONTENT_TYPE')if 'json' in content_type:data = json.loads(request.body)elif 'urlencoded' in content_type:data = request.body.decode('utf-8')# 将查询字符串拆分为键值对列表body_list = data.split('&')decode = {}for body in body_list:decode[body.split("=")[0]] = unquote(body.split("=")[1])print(decode)# 最终得到的解析后的字典data = decodeelif 'form-data' in content_type:data = request.body.decode('utf8')pattern = r'Content-Disposition: form-data; name="([^"]+)"\s*\r\n\s*\r\n(.*?)(?=\r\n|--.*?--|\Z)'res = re.findall(pattern, string=data)data = {i[0]: i[1] for i in res}request.data = datares = func(*args, **kwargs)return resreturn inner
  • urls.py

from django.urls import path,include
# BookView、BookDetailView 这个就是我在views.py 定义的类
from Api01.views import BookView,BookDetailView
urlpatterns = [path('books/', BookDetailView.as_view()),path('books/<int:pk>/', BookDetailView.as_view()),]

image-20240412204356592

  • 这个是View方法
@method_decorator(outter,'post')
# @method_decorator(outter,'delete')
class BookDetailView(View):def get(self, request, pk):res = Book.objects.filter(pk=pk).first()# 加个逻辑判断return JsonResponse({'code': 100, 'msg': '查询成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})def delete(self, request, pk):try:# 尝试从数据库中获取指定主键的对象book = Book.objects.get(pk=pk)except Book.DoesNotExist:# 如果对象不存在,则返回相应的 JSON 响应return JsonResponse({'code': 200, 'msg': '没有数据!!!'})# 如果对象存在,则删除它book.delete()# 返回删除成功的 JSON 响应return JsonResponse({'code': 100, 'msg': '删除成功'})def put(self, request, pk):# 跟post新增数据一样,编码格式不是json就会报错Book.objects.filter(pk=pk).update(**request.data)return JsonResponse({'code': 100, 'msg': '修改成功'})def post(self, request):# body gen body的使用方法# print(request.body)# ta = request.body# da = json.loads(ta)name = request.POST.get('name')price = request.POST.get('price')publish = request.POST.get('publish')# 保存任务到数据库res = Book.objects.create(name=name,price=price,publish=publish,)return JsonResponse({'code': 100, 'msg': '添加成功', 'result': {'name': res.name, 'price': res.price, 'publish': res.publish}})

image-20240412211832202

【三】APIView编写5个接口

  • 去除了csrf
    • 由于 RESTful API 通常是无状态的,不需要使用 CSRF 防护机制,因此 DRF 的 APIView 默认情况下去除了 CSRF 防护。
  • 包装新的request
    • 包装新的 request:APIView 提供了更灵活的请求(request)对象的访问方式,允许开发者更方便地访问请求中的数据以及请求的元数据。
  • 三大认证
    • APIView 支持多种身份验证方式,包括基于 Token 的认证、基于 Session 的认证、基于 OAuth 的认证等,使得开发者可以根据需求选择适合的认证方式。
  • 全局异常捕获
    • APIView 具有全局异常捕获的功能,可以捕获视图中发生的异常,并返回自定义的错误响应,提高了代码的可维护性和可靠性。

【0】注意事项

​ 视图(View)和API视图(APIView)都可以包含处理请求的逻辑,并且它们都可以执行相似的操作,比如从请求中获取数据、执行业务逻辑、与数据库交互等。

然而,它们之间仍然存在一些区别:

  1. 设计目的:视图通常用于渲染HTML页面,而API视图则用于处理API请求并返回数据,通常以JSON格式。
  2. 功能和便利性:API视图(特别是DRF中的APIView)通常提供了更多的功能和便利性,比如内置的请求处理方法(如getpost等)、序列化、验证、权限控制、分页等。这些功能可以帮助简化API开发并提高开发效率。
  3. 返回响应的方式:API视图通常使用DRF提供的Response对象来返回响应,而视图可能使用Django的render函数或者HttpResponse对象。

​ 虽然视图和API视图在处理请求的逻辑上可能非常相似,但是选择合适的工具(视图或API视图)取决于你的具体需求和项目的特点。如果你正在构建一个RESTful API,那么使用API视图可能会更加合适和便捷。

【1】主路由urls.py

from django.contrib import admin
from django.urls import path,include # 路由分发urlpatterns = [path('admin/', admin.site.urls),path('task_api/', include('task_api.urls')),
]

【2】子路由urls.py

from django.urls import path,include,re_path
from task_api.views import TaskAPIView ,TaskDetailView # TaskViewurlpatterns = [# re_path(r'(?P<id>\d+)?/?$', TaskAPIView.as_view()),re_path(r'(?P<pk>\d+)?/?$', TaskDetailView.as_view()),
]

【3】views.py

from django.http import JsonResponse
from .models import Task 
import time
import uuidfrom rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class TaskAPIView(APIView):def post(self, request):# 获取POST请求中的数据task_name = request.POST.get('task_name')task_desc = request.POST.get('task_desc')# 生成任务时间task_time = time.strftime('%Y-%m-%d')# 生成任务IDtask_id = uuid.uuid4()# 保存任务到数据库Task.objects.create(task_name=task_name,task_desc=task_desc,task_time=task_time,task_id=task_id)# 返回JSON响应    是一个HTTP状态码返回成功则是"201 Created"return Response({'message': 'Task 添加成功!'}, status=status.HTTP_201_CREATED)def get(self,request):res_list = Task.objects.all()data_list = []for res in res_list:data_list.append({'task_name': res.task_name,'task_desc':res.task_desc,'task_time':res.task_time,'task_id':res.task_id})return JsonResponse({'code': 100, 'msg': '查询成功', 'results': data_list})class TaskDetailView(APIView):def get(self,request,pk):if pk:try:task = Task.objects.get(pk=pk)print(task)data = {'task_name': task.task_name,'task_desc': task.task_desc,'task_time': task.task_time,'task_id': task.task_id}print(data)return JsonResponse(data)except Task.DoesNotExist:return JsonResponse({'error': 'Task 未能发现数据'}, status=404)def delete(self, request, pk):if pk:try:Task.objects.filter(pk=pk).delete()return JsonResponse({'code': 100, 'msg': '删除成功'})except Task.DoesNotExist:return JsonResponse({'error': 'Task 未能发现数据'}, status=404)def put(self, request, pk):if pk:try:Task.objects.filter(pk=pk).update(**request.data)return JsonResponse({'code': 100, 'msg': '修改成功!!!'})except Task.DoesNotExist:return JsonResponse({'error': 'Task 未能发现数据'}, status=404)

image-20240412190754671

image-20240412190819207

问:

​ 这个**request.data按你所说就是一个将Task表中的数据渲染到前端然后在解包打印到后端的过程对不对

答:

​ 不完全正确。request.data并不是将数据库中的数据直接渲染到前端,而是在Django REST Framework中用于获取HTTP请求中发送的数据的方式之一。具体来说,request.data是一个包含了HTTP请求主体中发送的数据的字典,它可能是通过POST、PUT或PATCH等HTTP方法发送的。

​ 在你的情况下,假设你使用的是PUT方法来更新任务的数据,那么request.data将包含前端发送的要更新的任务数据。而**request.data这个语法是将这个字典中的键值对解包为关键字参数,然后将这些参数传递给update()函数,以更新数据库中对应任务的数据。

​ 所以,request.data不是将数据库中的数据直接渲染到前端,而是用于获取HTTP请求中发送的数据,并在后端进行处理和操作。

request.data-->请求体的数据--》方法包装成了数据属性

这篇关于DRF的接口使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/946032

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念