drf之Restful规范序列化和反序列,drf介绍和快速使用和APIView源码分析

目录
  • 一、Restful规范
    • 10条规范
      • 1 数据的安全保障,通常使用http协议进行传输
      • 2 url地址中带接口标识:一般这样
      • 3 多版本共存,url地址中带版本信息
      • 4 数据即是资源,均使用名词:
      • 5 资源操作由请求方式决定
      • 6 url地址中带过滤条件 ?后带过滤条件
      • 7 响应状态码(http响应中带状态码)
      • 8 返回的数据中带错误信息
      • 9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
      • 10 返回的结果中带url链接
  • 二、序列化和反序列
    • 序列化:
    • 反序列化:
  • 三、作业:基于django原生编写5个接口
    • models.py
    • urls.py
    • views.py
  • 3 drf介绍和快速使用
    • 3.1 drf介绍
      • 下载:(有个坑)
    • 3.2 drf快速使用(不需要会)
      • urls.py
      • views.py
      • 序列化类 serializer.py
  • 五、 drf之APIView源码分析
  • 4.1 基于APIView的5个接口
      • 4.2 CBV源码分析
      • 4.3 APIView执行流程分析

一、Restful规范

RESTful是一种定义API接口的设计风格,AIP接口的编写规范,,尤其适用于前后端分离的应用模式中

这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源

我们可以使用任何一个框架都可以实现符合restful规范的API接口

10条规范

1 数据的安全保障,通常使用http协议进行传输

2 url地址中带接口标识:一般这样

	-http://api.baidu.com
    -http://www.baidu.com/api

3 多版本共存,url地址中带版本信息

	http://api.baidu.com/v1/login/
	http://api.baidu.com/v2/login/

4 数据即是资源,均使用名词:

    url地址尽量使用名词
    # 接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
    http://api.baidu.com/users
    http://api.baidu.com/books
    http://api.baidu.com/book
    注:一般提倡用资源的复数形式,在url链接中不要出现操作资源的动词,错误示范:http://api.baidu.com/delete-user

    # 特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
    http://api.baidu.com/place/search
    http://api.baidu.com/login

5 资源操作由请求方式决定

	#操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
    http://api.baidu.com/books   - get请求:获取所有书
    http://api.baidu.com/books/1 - get请求:获取主键为1的书
    http://api.baidu.com/books   - post请求:新增一本书书
    http://api.baidu.com/books/1 - put请求:整体修改主键为1的书
    http://api.baidu.com/books/1 - delete请求:删除主键为1的书

6 url地址中带过滤条件 ?后带过滤条件

	http://api.baidu.com/books -get请求表示查询所有图书,要查名字中有红的图书
	http://api.baidu.com/books?name_contains=红
	http://api.example.com/v1/zoos?limit=10:指定返回记录的数量
    http://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
    http://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
    http://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
    http://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

7 响应状态码(http响应中带状态码)

-http的响应状态码:http://blog.csdn.net/meng2lin/article/details/128955775
    -1xx:请求正在处理
    -2xx:请求成功 200  201
    -3xx:重定向
    -4xx:客户端错误
    -5xx:服务的错误
-http的响应的数据中带状态码(公司自己规定的)
	-{code:100}

8 返回的数据中带错误信息

	{code:101,msg:用户名或密码错误}
	{code:100,msg:成功}

9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范

    GET  /books:返回资源对象的列表(数组)
		-[{name:金瓶,price:88},{name:西游记,price:88}]
    	-{code:100,msg:成功,data:[{name:金瓶,price:88},{name:西游记,price:88}]}
    GET /books/1:返回单个资源对象
    	-{name:金瓶,price:88}    ---{code:100,msg:成功,data:{name:金瓶,price:88}}
    POST /books:返回新生成的资源对象
    	-{id:4,name:金瓶,price:88}  ---{code:100,msg:成功}
    PUT /books/4:返回完整的资源对象
    	-{id:4,name:金瓶,price:188}  ---{code:100,msg:修改成功}
    DELETE /books/4: 返回一个空文档      ---{code:100,msg:删除成功}

10 返回的结果中带url链接

二、序列化和反序列

api接口开发,最核心最常见的一个过程就是序列化

序列化:

把我们识别的数据转换成指定的格式提供给别人。
例如:我们在django中获取到的数据默认是模型对象(queryset),但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人。

反序列化:

把别人提供的数据转换/还原成我们需要的格式。
例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中
ps:
序列化:drf称为 read 序列化
反序列化:drf称为 write 反序列化

三、作业:基于django原生编写5个接口

book表为例,写5个接口(后面你写的所有接口,都是这5个,及其变形)
-查询所有图书
-新增一本图书
-修改一本图书
-查询一本图书
-删除一本图书

models.py

from django.db import models

# Create your models here.


class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()
    publish = models.CharField(max_length=32)

urls.py

from app02 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/api/', views.BookView.as_view()),
    path('books/api/<int:pk>/', views.BookDetailView.as_view()),
]

views.py

from django.shortcuts import render,HttpResponse

# Create your views here.

from django.http import JsonResponse
from .models import Book
from django.views import View

import json
class BookView(View):
    def get(self, request):
        # 查询出所有的图书,queryset对象,不能直接给前端
        books = Book.objects.all()
        # 转成json格式,给前端
        # 把queryset对象转成列表,然后再使用JsonResponse
        book_list = []
        for book in books:
            book_list.append({'name':book.name,
                              'price':book.price,
                              'publish':book.publish})
        # 拓展做了解
        # return HttpResponse(json.dumps(book_list,ensure_ascii=False))
        # 指定ensure_ascii为false,前端就显示中文了
        return JsonResponse(book_list, safe=False, json_dumps_params={'ensure_ascii': False})  # JsonResponse只能放字典或列表

        # 新增一个(只能使用urlencoded或form-data编码,使用json形式编码不行,因为json格式编码提交的数据,不能从request.POST中取,从body中)
    def post(self, request):
        # 取出前端传入的数据
        name = request.POST.get('name')
        price = request.POST.get('price')
        publish = request.POST.get('publish')
        # 存到数据库中
        book = Book.objects.create(name=name, price=price, publish=publish)
        # 返回新增的对象字典
        return JsonResponse({'name': book.name, 'price': book.price, 'publish': book.publish})

class BookDetailView(View):
    # 获取单条
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        # book 模型对象转成字典,使用JsonResponse返回
        return JsonResponse({'id': book.id, 'name': book.name, 'price': book.price, 'publish': book.publish})

    def put(self, request, pk):  # request.POST只能取post提交的urlencoded或form-data编码数据,put提交的取不到
        # 查到要改的
        book = Book.objects.filter(pk=pk).first()
        # 取出前端传入的数据,修改完,保存-----》存在问题,因为put提交的取不到
        # book.name = request.POST.get('name')
        # book.price = request.POST.get('price')
        # book.publish = request.POST.get('publish')
        # book.save()

        # 前端使用json格式提交,自己保存
        print(request.body)
        book_dic = json.loads(request.body)
        book.name = book_dic.get('name')
        book.price = book_dic.get('price')
        book.publish = book_dic.get('publish')
        book.save()

        return JsonResponse({'id': book.id, 'name': book.name, 'price': book.price, 'publish': book.publish})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return JsonResponse(data={})

3 drf介绍和快速使用

3.1 drf介绍

django 中有个app,djangorestframework:drf,帮助我们,快速实现符合resful规范的接口

下载:(有个坑)

pip3.8 install djangorestframework==稍微将版本

如果你是django2, 直接这样装,装最新drf,他们不匹配---》pip会自动把django卸载,安装最新django,安装最新drf
django3 ,这样没有任何问题
pip3.8 install djangorestframework --upgrade
image

ps:补充一点点东西:
-如果写了一个包,或app,想给别人用---》把你写的包,放到pypi上别人pip install 安装---》使用

3.2 drf快速使用(不需要会)

urls.py

from app01.views import BookView
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('books', BookView, 'books')
urlpatterns = [
]
urlpatterns += router.urls

views.py

from .serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

序列化类 serializer.py

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

五、 drf之APIView源码分析

4.1 基于APIView的5个接口

视图类

from rest_framework.views import APIView  # APIView继承了djagno原来的View
from .serializer import BookSerializer
from rest_framework.response import Response


class BookView(APIView):
    # 查询所有
    def get(self, request):
        book_list = Book.objects.all()
        # drf提供了序列化类(先别关注)
        ser = BookSerializer(instance=book_list, many=True)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    def post(self, request):
        ser = BookSerializer(data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})


class BookDetailView(APIView):
    # 查询单条
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, many=False)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    # 修改一条
    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})
from rest_framework.views import APIView  # APIView继承了djagno原来的View
from .serializer import BookSerializer
from rest_framework.response import Response


class BookView(APIView):
    # 查询所有
    def get(self, request):
        book_list = Book.objects.all()
        # drf提供了序列化类(先别关注)
        ser = BookSerializer(instance=book_list, many=True)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    def post(self, request):
        ser = BookSerializer(data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})


class BookDetailView(APIView):
    # 查询单条
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, many=False)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    # 修改一条
    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

序列化类

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

路由

urlpatterns = [
    path('books/', BookView.as_view()),
    path('books/<int:pk>/', BookDetailView.as_view()),
]

4.2 CBV源码分析

# cbv写法:
	1 视图中写视图类,继承View,写跟请求方式同名的方法
    	class BookView(View):
            def get(self,request):
                return 四件套
     2 在路径用写
    	path('books/', BookView.as_view())
        
        
        
# 如上写法,为什么能够执行

# 前置条件:前端请求,一旦路径匹配成功,就会执行  BookView.as_view()(request传入,)
# 入口在  BookView.as_view()--->执行结果---》View中有个as_view类的绑定方法
    @classmethod
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            res=self.dispatch(request, *args, **kwargs)
            return res
        return view
    
# 执行结果是view 的内存地址: 请求来了,执行view(request)
	path('books/', view)
    
# 执行 View类中的as_view方法中的内层的view函数,路由匹配成功,本质是在执行
	self.dispatch(request, *args, **kwargs)
    # self是谁的对象?BookView的对象
    # 去BookView中dispatch,找不到,去父类,View中找到了
    
    
# View这个类的dispatch
    def dispatch(self, request, *args, **kwargs):
        # request.method.lower() 如果是get请求,  ‘get’ 在这个列表里面
        if request.method.lower() in self.http_method_names:
            # handler=getattr(BookView的对象,'get')   
            # handler就是BookView类中的get方法
            handler = getattr(self, request.method.lower())
        else:
            handler = self.http_method_not_allowed
        # 执行 BookView类中的get方法 (request)
        return handler(request, *args, **kwargs)
    
# 最终本质跟写fbv的执行流程一样
# 最终结论:什么请求方式,就会执行视图类中的什么方法

4.3 APIView执行流程分析

# 有了drf,后期都写CBV,都是继承APIView及其子类
# 执行流程:
	-入口:path('books/', BookView.as_view())---》请求来了,执行BookView.as_view()(request)
    -as_view 是谁的? APIView的as_view
        @classmethod
        def as_view(cls, **initkwargs):
            # super()代指的是:父类对象  View类的对象
            # View的as_view(**initkwargs)----》执行结果是view,是View类的as_view方法中的view
            view = super().as_view(**initkwargs)
            view=csrf_exempt(view)  # 局部禁用csrf,
            return view
        
  	-path('books/', View类的as_view中的view,只是去掉了csrf的认证)
	-请求来了,执行 【View类的as_view中的view,只是去掉了csrf的认证(request)】
    -执行:self.dispatch(request, *args, **kwargs),  self要从根上找
	-self.dispatch 是APIView的dispatch,源码如下
        def dispatch(self, request, *args, **kwargs):
            # request 是新的request,      request是老的request
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
            try:
                # 执行了认证,权限和频率
                self.initial(request, *args, **kwargs)
                # 在执行视图类方法之前,去掉了csrf认证,包装了新的request,执行了认证频率和权限
                #### 执行请求方式字符串对应的方法
                if request.method.lower() in self.http_method_names:
                    handler = getattr(self, request.method.lower(),
                                      self.http_method_not_allowed)
                else:
                    handler = self.http_method_not_allowed
                response = handler(request, *args, **kwargs)
            except Exception as exc:
                response = self.handle_exception(exc)
                
            # 无论是在三大认证,还是视图类的方法中,出现错误,都会被异常捕获,统一处理
            self.response = self.finalize_response(request, response, *args, **kwargs)
            return self.response
    

    
# 总结:
	1  以后只要继承APIView的所有视图类的方法,都没有csrf的校验了
    2  以后只要继承APIView的所有视图类的方法 中的request是新的request了
    3  在执行视图类的方法之前,执行了三大认证(认证,权限,频率)
    4  期间除了各种错误,都会被异常捕获,统一处理
        
        
        
# 补充(装饰器语法糖):
	fbv,局部禁用csrf,如何写?
    @csrf_exempt
    def index(request):
        pass
    
    本质原理是(装饰器本质):index=csrf_exempt(index)

作业

# 1  写完booke的剩余3个接口
# 2  按照我写的,照着敲(基于APIView的5个接口)

# 3 走一遍cbv和APIView的源码
# 高级:可以不写
	-写一个装饰器,装饰在fbv上,这个fbv可以接受前端的编码格式可以是urlencoded,form-data,json,取数据,都是从request.data中取
######### 1 作业讲解############
def load_json(func):
    def inner(request, *args, **kwargs):
        try:
            request.data = json.loads(request.body)  # 如果是json格式,就成功;如果是其他格式,直接就报错了
        except Exception as e:
            request.data = request.POST
        res = func(request, *args, **kwargs)
        return res

    return inner


@load_json
def books(request):
    # post提交数据,urlencoded,form-data,json

    print(request.data)
    print(request.FILES)
    return JsonResponse({'code': 100, 'msg': '成功'})
本文转载于网络 如有侵权请联系删除

相关文章

  • 数十亿行代码训练,GitHub原生AI代码生成工具上线,网友:要终结编程?

    GitHubCopilot是一个AI代码合成器,并不是搜索引擎:它提出的绝大多数代码建议都是新生成的,此前从未出现过。简而言之,这就是未来。在项目开发中,优秀的代码自动补全工具可以提升工作效率。然而,传统的IDE基本都使用搜索方法进行补全,在一些场景下效果不佳。今日,GitHub和OpenAI联合发布了新的AI代码补全工具GitHubCopilot,并展示了技术预览版。该工具可以在VSCode编辑器中自动完成代码片段,这也是OpenAI接受微软10亿美元投资以来的首个重大成果。目前,GitHubCopilot项目还只是严格的技术预览版,用户可以在主页注册报名,将有机会访问试用。GitHubCopilot注册地址:https://github.com/features/copilot/signup对于GitHub和OpenAI推出的这款全新AI代码补全工具,网友们给出了极高的评价。下面这位用户大致可以代表大多数试用者的心声。ta表示:「我使用Alpha版两周了,Copilot似乎能够准确地知道我接下来要输入的内容,这令我大受震撼。有时它甚至建议我要查找的内容,例如选择随机十六进制随机码的

  • 带你快速掌握Scala操作———(1)

    前一段时间给大家简单介绍了Scala以及Scala的环境安装,还没看的小伙伴可以先去看一看,把环境配置好。Scala快速入门简介——(一) Scala之开发环境安装——(二)一定要先去看这两篇,配置好环境,才可以进行操作哦!!!!!!1、scala解释器后续我们会使用scala解释器来学习scala基本语法,scala解释器像Linux命令一样,执行一条代码,马上就可以让我们看到执行结果,用来测试比较方便。启动scala解释器要启动scala解释器,只需要以下几步: 按住windows键+r  输入scala即可复制执行scala代码在scala的命令提示窗口中输入println(“hello,world”),回车执行退出解释器在scala命令提示窗口中执行:quit,即可退出解释器2、声明变量语法格式Java变量定义inta=0;复制在scala中,可以使用val或者var来定义变量,语法格式如下:val/var变量标识:变量类型=初始值复制其中 val定义的是不可重新赋值的变量  var定义的是可重新赋值的变量  scala中定义变量类型写在变量名后面  scala的语

  • python 异常处理

    异常广义上的错误分为错误和异常错误指的是可以人为避免异常是指在语法逻辑正确的而前提下,出现的问题在python中,异常是一个类,可以处理和使用异常的分类BaseException所有异常的基类复制Exception常见错误的基类复制ArithmeticError所有数值计算错误的基类复制Warning警告的基类复制AssertError断言语句(assert)失败复制AttributeError尝试访问未知的对象属性复制DeprecattionWarning关于被弃用的特征的警告复制EOFError用户输入文件末尾标志EOF(Ctrl+d)复制FloattingPointError浮点计算错误复制FutureWarning关于构造将来语义会有改变的警告复制GeneratorExitgenerator.close()方法被调用的时候复制ImportError导入模块失败的时候复制IndexError索引超出序列的范围复制KeyError字典中查找一个不存在的关键字复制KeyboardInterrupt用户输入中断键(Ctrl+c)复制MemoryError内存溢出(可通过删除对象释放内存

  • Java社区领袖联合发文:别慌,Java仍然是免费的!

    在去年的JavaOne上,MarkCavage当时宣布Oracle将逐步开源OracleJDK的专有功能(商业特性)。OracleJava平台产品管理高级总监DonaldSmith曾在一篇博客文章中写道,他们的目的是让OpenJDK版本和OracleJDK二进制文件之间没有技术差异。  但关于OpenJDK和OracleJDK以及其他服务商提供的变种版本,各自的许可证是什么,又都提供哪些服务和支持,让许多Java开发者理不清头绪,容易混淆。Oracle7月份启用新的JavaSE订阅模式的消息一出,更是让许多开发者认为是不是代表Java以后要收费?  为解答Java社区的疑惑,超过30位Java社区领袖和专家共同创建了一个Google文档,里面详细描述了各版本之间的区别,并对一些常见问题进行了答疑。文档分为“短版本”和“长版本”,建议所有Java开发者研读。  文档中强调,开发者仍然可以免费获得OracleJDK、Oracle的OpenJDK,以及其他服务商提供的OpenJDK:OpenJDK社区创建并维护(GPLv2+CE许可)JavaSE规范的开源参考实现(RI),受JCP(Java

  • K8S 生态周报| containerd v1.3.2 发布

    「K8S生态周报」内容主要包含我所接触到的K8S生态相关的每周值得推荐的一些信息。欢迎订阅知乎专栏「k8s生态」。1Kindv0.6.1发布本周KindKubernetesInDocker发布了v0.6.1版本,这是对v0.6.0的一个小patch版本,主要变更如下:修复containerd在多controlplane节点集群下的配置;修正了v1alpha4API中的protocol和propagation配置;重新推送了镜像,v0.6.0发布的时候忘记把CNI的镜像给预加载到Node镜像中了。现在的默认镜像是kindest/node:v1.16.3@sha256:70ce6ce09bee5c34ab14aec2b84d6edb260473a60638b1b095470a3a0f95ebec另外:Kind的Node镜像在DockerHub上的下载量超过了500K+,也说明其正在被广泛使用。(查看了下我自己发布的镜像中,下载量最多的也才只有50K+)恭喜Kind!2containerdv1.3.2发布这是containerd在v1.3系列的第二个patch版本。此版本主要的修复内容如下:

  • DSP之Cookie Mapping

    程序化广告是以人为中心实现的精准投放,首先就应该要识别到人,而程序化广告是由多个平台或参与者合作完成的,用户的流量方向是网站-SSP-AdX-DSP-广告主着陆页,各方都有自己的ID系统,基本上,DSP有一套自ID识别系统,ADX也有一套自己的ID识别系统,网站主要通过cookie识别人,不同参与者命名的cookie方式不同,造成同一个人在不同平台的cookie是不同的,DSP的命名可能是AAA,而ADX的命名可能是111,浏览器安全模型限制了不同的cookie之间不能互相读取,这时就需要Cookiemapping去打通,可以将DSP的AAA和ADX的111对应起来,进而能够识别这个人,才可以做精准营销。CookieMapping只是针对网站的,因为APP上的设备ID是唯一的,不需要通过映射或匹配去是识别用户。我们先来看一下竞价的过程:1、用户浏览网站,网站是接入广告交易平台的,判断是否符合如何要求后向ADX发起广告请请求2、广告交易平台发起竞价活动,向不同的DSP发送bidrequest,里面会包含有访客信息3、DSP根据发送的信息,去自己的用户系统,DMP查询匹配出用户的信息后,根

  • 3天上手,30天精通!—— 深度学习FPGA加速器设计

    机器之心专栏作者:Pooterko本文的目标是帮助对于深度学习硬件加速器设计感兴趣的朋友快速上手基于FPGA的深度学习加速器设计。准备以下是阅读本文的基础,请做好下列基础准备后再上手加速器设计:C语言设计:熟练掌握C语言语法。计算机体系结构知识:参考书《计算机组成与设计》,不需要熟读全书,但要对一些加速器设计相关的基础概念有比较清晰的理解和认识,如流水线、数据并行等。高层次综合利用高层次综合工具,开发者只需要编写高级语言的代码完成程序功能,就能将高级语言编写的代码综合成相同功能的RTL级实现(基于Verilog或VHDL)。开发者还可以通过添加一些pragma的方式来指示和调整高层次综合工具生成的硬件模块的架构。整体而言,利用高层次综合工具进行FPGA硬件开发的过程,应该是利用软件语言的表达来描述硬件模块的过程。目前,高层次综合的代码都是基于C/C++/OpenCL的,所以对于没有硬件设计基础的朋友来说,利用高层次综合工具可以大幅度地降低学习难度,缩短开发周期,加快设计迭代速度。3天入门实例我们需要使用一个简单的实例来进行入门学习。既然目标是让大家快速上手深度学习加速器的硬件设计,那么

  • 七天速成小程序——喜马拉雅

    很多新手都喜欢一个人完成项目,从项目的规划、搭建,到实施、debug、验收,一整套流程都是自己纯手完成,当然,对于提高自己的整体开发能力和自适应能力很有帮助。ok,不废话,下面开始介绍小白如何快速完成一个微信小程序。喜马拉雅App比较大,这里只完成部分重要功能。。。本文章使用的是以喜马拉雅电台App防成微信小程序的栗子。您可以从这篇文章中获得以下技能点:选择项目需要的合适工具如何快速分析项目功能并组成列表如何快速完成并搭建一张页面,并为复用提供良好的接口如何应对短时间内无法解决的bug如何规划每一天的工作量和调整工作心态提前准备工具工具是非常重要的,当然,也是很简单的。。。编辑器(我使用的是vscode):@VisualStudioCode微信web开发者工具下载:@微信web开发者工具笔记(我使用的有道云):@有道云笔记github(每日提交一下):@githubmarkMan(基本的页面样式标注,大公司都有专门的ps设计师,这里将就一下):markManiconfont(阿里巴巴字体图标库):@iconfontweui(微信样式框架/这项目中css纯手写,新手建议纯手写,实在无法写

  • 校外实习项目需求说明文档——会员系统

    1 我的--首页      (1)可编辑“查看特权”的内容(图文)      (2)可编辑点击“分享”后的内容(图文),长按可以保存分享二维码/也可以右上角分享链接      2 我的--各功能模块详情 (1)累计收益   明细点进去以后包括:收入、支出、我的团队(推荐的人分类为个人、商家属性,显示会员的基本属性)、我要推广          (2)积分   更多玩法 点进去包括:一周签到显示,得积分说明、积分商城      (3)客服与帮助      (4)消息:包括动态(活动信息)+通知(系统通知)   1)通知       2)动态      

  • spring 循环依赖 分享笔记

    一、什么是循环依赖?A类的属性指向了B类的对象,B类的属性又指向了A类的对象。这就产生了循环依赖。 //A依赖了BclassA{publicBb;} //B依赖了AclassB{publicAa;}   二、我们自己写代码是否会产生循环依赖?当然会呀。我们是如何解决的。 但是,在Spring中循环依赖就是一个问题了,为什么? 因为,在Spring中,一个对象并不是简单new出来了,而是会经过一系列的Bean的生命周期,就是因为Bean的生命周期所以才会出现循环依赖问题。当然,在Spring中,出现循环依赖的场景很多,有的场景Spring自动帮我们解决了,而有的场景则需要程序员来解决,下文详细来说。   看一下代码的演示吧。CircularDependencyTest类main方法,屏蔽掉spring容器相关的代码。 我们再来看一下,spring循环依赖运行的结果CircularDependencyTest类main方法,屏蔽掉手动new类的代码,启动spring相关代码。   三、要明白Spring中的循环依赖,得先明白Spring中Bean的生命周期。1

  • Freezing

    Freezing 牛客小白月赛53F 首先有一个朴素的\(DP\),dp[i][j]表示前\(i\)个人中,且最后一个人的状态是\(j\)的方案数,然后暴力转移即可,复杂度\(O(n\times2^m)\)无法通过本题。 有一个不能通过本题的优化是,我们可以通过枚举~j的子集,来进行状态转移,赛时可以通过,赛后被出题人卡掉了。代码如下 #include<bits/stdc++.h> usingnamespacestd; usingll=longlong; #definerep(i,a,b)for(inti(a);i<=b;++i) #definedec(i,a,b)for(inti(b);i>=a;--i) template<typenameT>voidchkmax(T&x,Ty){x=max(x,y);} template<typenameT>voidchkmin(T&x,Ty){x=min(x,y);} constintMOD=998244353; inlineintmod(intx){returnx>=

  • js Date.parse() format.

    dateformat androidchrome linuxchrome Mobilesafari ioschrome windowssafari linuxfirefox windowschrome yyyy-MM-dd T T F F F F T Yyyy-MM-ddT   F F T F T   MM/dd/yyyy T T T T T T T dd/MM/yyyy F F F F F F F   support:MM/dd/yyyyHH:mm:ss   参考链接:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

  • P1886 滑动窗口 /【模板】单调队列

    单调队列 概念 一种需要人工根据一定条件,来筛除一些队列中已经没有资格再混下去的元素的数据结构 举例 张三原本在学校的OI队伍,但天天不思进取,上课只会打小游戏,结果...... 身为高二学长的他竟然连高一新晋的OIer都比不过,于是他们学校的yxf老师就将他开除了队伍,因为新晋OIer年纪比他小,能力比他强,张三的整体价值已经比不过新晋OIer了QwQ 性质 队列中的元素其对应在原来的列表中的顺序必须是单调递增的。 队列中元素的大小必须是单调递*(增/减/甚至是自定义也可以) 蒟蒻代码 #include<bits/stdc++.h> #definereregister usingnamespacestd; constintN=1e6+5; intn,k; intq[N];//存储元素索引,方便判断出队 inthead,tail; inta[N]; voidmonotoneMin(){ //memset(q,0,sizeof(q)); head=1,tail=0; for(reinti=1;i<=n;i++){ while(head<=tail&a

  • 1.django项目的创建(在CMD中)

    django项目的创建(在CMD中) 1.切换到你想要存储项目的位置,我这里保存在桌面上 cdDesktop 2.创建一个django项目,项目名叫guest django-adminstartprojectguest 3.切换到guest项目的目录中 cdguest 4.在guest项目中创建一个叫做sign的应用 pythonmanage.pystartappsign 5.执行manage.py里的runserver命令,将项目运行起来 pythonmanage.pyrunserver 如果需要指定端口启动则为:pythonmanage.pyrunserver127.0.0.1:8001 6.在guest目录下的settings.py下找到INSTALLED_APPS的数组中增加'sign', 7.在guest目录下的urls.py文件中添加 fromsignimportviews #然后在urlpatterns数组中添加 path('index/',views.index), 8.在sign目录下的views.py文件中添加如下代码 fromdjango.httpimportHt

  • 阿里云上的rds 的隔离级别read committed​ 而不是repeatable-read设置原因

    阿里云上的rds的隔离级别是readcommitted,而不是原生mysql的“可重复读(repeatable-read)”,他们是基于什么原因这样设置的? showvariableslike'transaction_isolation'; --结果如下 Variable_nameValue transaction_isolationREAD-COMMITTED复制   我们都知道:    提交读(不可重复读)和可重复读的区别在于:   - 提交读 :  在本事务未提交之前其他事务的增删改操作提交后会影响读的结果。 读的是最新结果 。   - 可重复读 :在读的过程中数据始终是事务启动时的数据状态,未提交之前其他事物的增删改操作提交后都不会影响读的结果。 读的是快照结果   也就是说,readcommitted隔离级别下,同一个事务中,多次读取数据,可能是不一样的, 因为数据有可能已经

  • 前端项目首屏加速 gzip打包 路由懒加载 cdn资源优化

    目前主流的Vue, React 等单页项目中build把所有开发遇到的代码打包在一起形成一个js和一个css,服务器请求, 然后加载js, css 等依赖进行渲染. 因此会经常遇到,个人写的项目,打开十分缓慢,需要加载很长时间才能加载完毕. 就算不是白屏,做了loading处理 但还是会很影响体验 排除服务器带宽实在太低, 服务器压力实在太大,文件的大小是速度的第一影响.   gzip打包 gzip打包很好理解. 请求的东西可以通过压缩的方式, 到了客户端再解压 采用nginx即可 配置方案   gzipon; gzip_buffers324k; gzip_comp_level6; gzip_min_length200;gzip_typestext/csstext/xmltext/plaintext/javascriptapplication/jsonapplication/javascriptapplication/x-javascriptap

  • Go 注意坑

    目录http请求后需关闭句柄解析请求参数中带”;“,解析出错时区map顺序遍历gorutine使用注意 http请求后需关闭句柄 大量请求没有关闭,会造成go的内存泄露。这也是平时编码习惯没有养成,需谨记。 务必请求后释放资源: response.Body.Close() 复制 解析请求参数中带”;“,解析出错 http://tj-adc.wtzw.com/click?source=wolong12;123344&project=reader_free&callback=__CALLBACK_URL__&channel=qi-guanfang_hc&ua=Dalvik%5C/2.1.0%20%28Linux;%20U;%20Android%209;%20V1813BA%20Build%5C/PKQ1.181030.001%29 复制 解析请求的时候发现ua参数“;”开始之后的字符串都被过滤了。 查看net/url包的源码, ... key:=query ifi:=strings.IndexAny(key,"&;");i>=0{ key,q

  • leetcode 450. Delete Node in a BST 删除二叉搜索树中的节点 (中等)

    一、题目大意 给定一个二叉搜索树的根节点root和一个值key,删除二叉搜索树中的key对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。 一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点; 如果找到了,删除它。 示例1: 输入:root=[5,3,6,2,4,null,7],key=3 输出:[5,4,6,2,null,null,7] 解释:给定需要删除的节点值是3,所以我们首先找到3这个节点,然后删除它。 一个正确的答案是[5,4,6,2,null,null,7],如下图所示。 另一个正确答案是[5,2,6,null,4,null,7]。 示例2: 输入:root=[5,3,6,2,4,null,7],key=0 输出:[5,3,6,2,4,null,7] 解释:二叉树不包含值为0的节点 示例3: 输入:root=[],key=0 输出:[] 提示: 节点数的范围[0,104]. -105<=Node.val<=105 节点值唯一 root是合法的二叉搜索树 -105<=

  • fabric2.2.网络部署

    警告 在执行测试项目时,多次使用并修改此文件,部分地方没有及时更新.如果问题请联系487008159更正. 必看 项目:fabric-samples 工作目录:~/go/src/github.com/hyperledger/fabric-samples/test-network 辅助脚本 身份环境变量 组织1 env-org1.sh #!/bin/bash exportFABRIC_CFG_PATH=$PWD/../config/ exportCORE_PEER_TLS_ENABLED=true exportCORE_PEER_LOCALMSPID="Org1MSP" exportCORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt exportCORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.exam

  • 工作流引擎

    由于单位要做工作流所以研究了几个工作流引擎,其中包括Activiti/camunda/Flowable/Jbpmn重点对比下Activiti/camunda/Flowable三个框架,因为这三个框架同宗同源,几乎都是从Jbpm4之后衍生出来的。我们项目中主要用了camundahttps://camunda.com/https://www.activiti.org/https://flowable.com/open-source/每个引擎都有工作流的画图,启动,用户,和接口。上面几个引擎基本都是java的。我们的想法是利用camunda跑基本的任务,然后在这个任务上挂自己的属性,比如说文档,然后当用户登录,看我的任务的时候可以看到以前都填写过什么文档,我现在需要填写什么文档。所以就出现了模型和任务,这是在后台定义的,模型采用的是单继承的类,任务可以使用这些模型类。本身任务也是一个模型,这样一个任务就可以挂许多文档了。说到工作流本身,每个工作流都有自己的restapi,就是http协议的接口,可以启动工作流,查看工作流。中间层和工作流交互就是用的这些restapi。每一个工作流引擎都有一个

  • HTTP协议

    引言                                        HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(NextGenerationofHTTP)的建议已经提出。HTTP协议的主要特点可概括如下:1.支持客户/服务器模式。2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务

相关推荐

推荐阅读