Welcome to kimi's blog

drf入门规范

DRF入门规范

DRF(django rest framework)是基于django的一个框架,可以帮助我们快速开发restful规范的的接口框架
DRF官方文档

后期学习资料

# 个人博客:https,证书过期,忽略
	-https://www.liuqingzheng.top/
# cnblogs博客(后期迁移到这里,高级部分的内容)
	-https://www.cnblogs.com/liuqingzheng 
# 知乎
	-https://www.zhihu.com/people/justin_liu

drf整体内容

1.入门规范
	web开发模式
	api接口
	接口测试工具
	restful规范
	序列化反序列化
	drf快速使用
	APIView,Request类
	drf把django的好多东西都重写了
2.序列化组件(重点)
	基本序列化类
	模型类序列化类
	如何序列化
	如何反序列化
	反序列化的数据校验功能
3.请求与响应
	drf的request已经不是原来django的request了
	drf的reponse已经不是原来django的reponse了
	指定可以接收请求的编码方式
	指定响应格式
4.视图组件(重点)  View
	两个视图基类
	5个视图拓展类
	9个视图子类
	视图集
5.路由
	自动生成路由
	
6.认证(登录认证)、权限、频率(重点)
7.过滤、排序、分页(次重点)
8.手动、自动生成接口文档
9.JWT登录认证的,区别于cookie和session(目前是主流)
10.后台管理美化(django原生,simpleui二次开发)
11.基于角色的访问控制、权限的控制

web 应用模式

django web框架,其实用来写web项目,之前学习的BBS项目,图书管理系统都是用的前后端混合开发的项目,今天开始学习的是前后端分离的项目

前后端混合开发项目

  1. 后端人员,既要写后端代码也要写前端的模板语法【xxx.html】,也就是xxx.html的python代码

  2. 全栈开发,是前后端混合时代

    image

image

前后端分离项目

  1. 后端人员只需要写后端逻辑和接口,前端页面渲染有前端人员负责

  2. 全栈开发,web后端,前端框架(vue,react)

    image

image

API接口

概念

API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。API除了有应用“应用程序接口”的意思外,还特指 API的说明文档,也称为帮助文档。

API:应用程序接口(API:Application Program Interface)

应用程序接口是一组定义、程序及协议的集合,通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过调用 API 函数应用程序进行开发,可以减轻编程任务。 API 同时也是一种中间件,为各种不同平台提供数据共享。

简单理解API

防止因个人习惯差异引起的混乱接口,找到并形成团队有共识、统一的接口规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本(前后端)

通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介

	http://127.0.0.1/book/
	 点赞、点踩   就是API接口

API接口:前后端交互的媒介
前端指的是大前端,不仅仅是网站了,还有app/小程序;后端:python/go/java....的web后端,目前使用的是python的django写后端

    url地址:https://api.map.baidu.com/place/v2/search
    请求方式:get  post  delete  put .....
    请求参数:json格式的key-value类型数据
    # 请求数据:地址栏中数据--》request.GET,请求体中数据:requsest.POST
        早些年  前后端交互使用xml格式   ajax其实就是异步JavaScript和XML
        后来    随着json格式的出现,乃至今都是主流
        未来    更高效、安全的交互格式会替代目前的Json格式
    响应结果:json格式的数据

API接口案例

https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=上海&query=肯德基&output=xml
    
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=上海&query=肯德基&output=json


xml与json格式的区别?

  1. JSONJavaScript Object NotationXML是可扩展标记语言
  2. JSON是基于JavaScript语言;XML源自SGML
  3. JSON是一种表示对象的方式;XML是一种标记语言,使用标记结构来表示数据项。
  4. JSON不提供对命名空间的任何支持;XML支持名称空间。
  5. JSON支持数组;XML不支持数组。
  6. XML的文件相对难以阅读和解释;与XML相比,JSON的文件非常易于阅读。
  7. JSON不使用结束标记;XML有开始和结束标签。
  8. JSON的安全性较低;XMLJSON更安全。
  9. JSON不支持注释;XML支持注释。
  10. JSON仅支持UTF-8编码;XML支持各种编码

前端、前台、后端及后台的区别

前后端是指代码上的,前后台是指用户视觉上的。

image

接口测试工具postman

后端写好了接口,测试通过接口测完才能上线。引入接口测试软件工具postman

测试工具有:

浏览器只能发送`get`请求,不能自动发送`post/delete`请求

1.`postman`:开始是开源软件,只是谷歌浏览器的插件,后面越做越好,后面就可以安装到操作系统,后来就收费了
2.`postwoman`
3.其他的,不同公司可能不一样

注意:测试工具只是用来发送http请求

postman下载

官方下载:https://www.postman.com/downloads/?utm_source=postman-home

软件:Postman-win64-Setup.exe

使用:双击即可

postman基本使用

# 请求体的编码格式
    urlencoded:默认情况--->key value形式--->组成成name=kiki&age=18  放到了请求体中request.boby
    form-data:传文件和数据,组装成很复杂形式,暂时先不讲,从request.body中一取就报错
    json格式:放在body体中{"name":"kiki","age":19}
 
# 返回数据
    body:响应体
            如果是浏览器就是看到的页面;
            如果是postman就是下面第三张图片显示的形式
         响应头
         响应的cookie

image

image

image

restful规范

概念

REST全称是Representational State Transfer,中文意思是表述:表征性状态转移,它首次出现在2000年Roy Fielding的博士论文中。

Restful是一种定义Web API接口的设计风格,尤其使用于前后端分离的应用模式中

restful 10规范

  1. 数据的安全保障,通常使用https(http+ssl/tsl)协议

    url链接一般都采用https协议进行传输

    采用https协议,可以提高数据交互过程中的安全性

  2. 接口中带api标识

    https://api.kiki.com/books
    https://www.kiki.com/api/books   常用接口形式
    
  3. 多版本共存,路径中带版本信息

    https://api.kiki.com/v1/login
    https://api.kiki.com/api/v2/login
    
  4. 数据即是资源,均使用名词,尽量不出现动词(最核心的)

    接口一般都是完成前后台数据的交互,交互的数据我们称之为资源

    接口形式如下:

    https://api.baidu.com/users
    https://api.baidu.com/books   
    

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

  5. 资源操作由请求方式决定(method)

    操作资源一般都会涉及到增删改查,提供请求方式来标识增删改查动作

    https://api.baidu.com/books    get请求:获取所有图书 
    https://api.baidu.com/books/1  get请求:获取主键为1的书  
    https://api.baidu.com/books    post请求:新增一本图书   
    https://api.baidu.com/books/1  put请求:修改主键为1的书   
    https://api.baidu.com/books/1  delete请求:删除主键为1的书  
    
  6. 在请求地址中带过滤条件

    https://api.baidu.com/books?name=kiki&price=99
    
  7. 响应中状态码:两套

    http响应状态码:1xx:请求正在处理,2xx:成功响应,3xx:重定向,4xx:客户端错误,5xx:服务端错误
          状态码详细信息:https://blog.csdn.net/li_chunlong/article/details/120787872
    
    公司内部规定的响应状态码,放在响应体中
    	{code:0}  后期一般使用100  101  102 这种状态码
    
  8. 返回数据中带错误信息

    {
        code:0
        mag:"ok/用户名错误"
    }
    
  9. 返回的结果应该符合一下规范 ---好多公司不遵循这个

    GET 获取所有数据:返回资源对象的列表(数组)[{"name":"红楼梦","price":99},{"name":"红楼梦","price":99},{"name":"红楼梦","price":99}]
    GET 单个对象:返回单个资源对象:{"name":"红楼梦","price":99}
    POST 新增对象:返回新生成的资源对象:{"name":"西游记","price":99}
    PUT 修改对象:返回完整的资源对象:{"name":"西游记","price":100}
    DELETE 删除:返回一个空文档
    
  10. 响应数据中带链接

序列化反序列化

api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把[数据转换格式],序列化可以分为两个阶段:

序列化

把程序员识别的数据转换成指定的格式提供给别人。

字典、列表以json格式存进文件中

举例:在django中获取到的数据默认是模型对象,但模型对象数据无法直接提供给前端或别的平台使用,所以需要把数据进行序列化,变成字符串或者json数据,提供给别人

read:读取数据库信息>>>序列化的过程

反序列化

把别人提供的数据转换/还原成程序员需要的格式

举例:前端js提供过来的json数据,对于python而已就是字符串,需要进行反序列化成模型类对象,通过os模块将数据保存到数据库中

write:将别人的数据转换后写入数据中>>>:反序列化的过程

基于django原生编写5个接口

# 以后写的接口,基本都是5个接口及其变形
    查询所有:JsonResponse   HttpResponse
    查询单个:根据pk查到单个对象,直接序列化后返回给前端
    新增一个:request.POST 取出前端传入body的数据,只能取出form-data,urlencoded,不能取出josn格式,request.body  --->json--->反序列化成字典,再用(name=lqz&age=19)
    修改一个:put请求放到body中的数据,在request.POST取不出来,只能自己从request.body中取出来
    删除一个:通过pk直接删除
# 基于books单表为例,写5个接口
    创建book表
    表迁移
    录入表的数据:直接录入/后台管理录入
    写查询所有接口   遵循restful规范,使用cbv
    新增一个数据 post()
    查询一个数据 get()
    修改一个数据:put提交的数据,不能从requets.POST中提取,>>>request.body
    删除一个数据 delete()
  1. 创建表book

image

  1. 表迁移、录入表的数据:直接录入/后台管理录入

image

  1. 写查询所有接口 遵循restful规范,使用cbv

    用到get请求,注释crsf第四个中间件

    from django.views import View
    from .models import Book
    from django.http import JsonResponse
    
    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,前端页面就显示中文了
            """
            1.safe=False
            'In order to allow non-dict objects to be serialized set the ''safe parameter to False.'
            book_list是列表,想要序列化,要把safe=False
            
            2.底层函数
            def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
                     json_dumps_params=None, **kwargs):
                if safe and not isinstance(data, dict):
                    raise TypeError(
                        'In order to allow non-dict objects to be serialized set the '
                        'safe parameter to False.'
                    )
                if json_dumps_params is None:
                    json_dumps_params = {}
                kwargs.setdefault('content_type', 'application/json')
                data = json.dumps(data, cls=encoder, **json_dumps_params)
                super().__init__(content=data, **kwargs)
            
            
            3.底层数据是把数据打散后传入的
             data = json.dumps(data, cls=encoder, **json_dumps_params)
            """
            return JsonResponse(book_list,safe=False,json_dumps_params={'ensure_ascii':False}) # JsonResponse一般传字典和列表,可以通过查看源码可知json格式支持传数据类型
    
    

    前端展示,注意safe=False json_dumps_params={'ensure_ascii':False}
    image

  2. 新增一个数据

新增一个(只能使用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})

!image

使用json格式的话,响应结果都是none,因为json格式编码提交的数据,不能从request.POST中取,从body中)

  1. 查询一个数据

    路由不一样,需要新写一个路由,可用转换器或者正则表达式,但使用转换器较多

    # 获取图书,修改图书,删除图书
    path('api/v1/books/<int:pk>',views.BookView.as_view()),
    # re_path('api/v1/books/(?P<pk>\d+)',views.BookView.as_view())
    

    因为获取单条数据也是get请求,第一个CBV类已有一个get请求的情况下,需要再开一个CBV类

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

    request.POST只能取post提交的urlencodedform-data编码数据,put提交的取不到

        def put(self,request,pk):
            # 查询要改的
            book = Book.objects.filter(pk=pk).first()
            # 取出前端传入的数据,修改完保存,>>>存在问题,因为put提交的取不到
            # book.name=request.POST.get('name')  # put请求取不到name
            # book.price=request.POST.get('price')
            # book.publish=request.POST.get('publish')
            # book.save() # 保存
            """request.POST只能取post提交的urlencoded或form-data编码数据,
            put提交的取不到
            """
            # 前端使用json格式提交,自己保存
            print(request.body)
            book_dict = json.loads(request.body)
            book.name = book_dict.get('name')
            book.price = book_dict.get('price')
            book.publish = book_dict.get('publish')
            book.save()
            return JsonResponse({'id': book.pk, 'name': book.name, 'price': book.price, 'publish': book.publish})
    
  3. 删除一个数据

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

drf介绍和快速使用

DRF官方文档

djangorestframework drf 帮助快速实现符合restful规范的接口,目前django 最新版本是4.x ,一般都会用最新版的上一版3.x,drf最新版支持到django 3.x ,最新版不支持django 2.x
drf介绍

  • djagno的一个app(组件),最新版本 3.x---》支持djagno 3.x以上
  • 框架,模块版本不一致导致程序运行不起来
  • 方便我们快速的在django框架上编写符合restful规范的接口

drf的下载与安装

pip3.8 install djangorestframework -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/

注意:目前下载的django是 2.2.2 版本,下载 drf会发现django版本太低不支持,下载drf会自动安装最新版django 4.x;如果下载的是django 3.x,下载drf不会有任何影响

drf编写5个接口(了解)

# views中
from .serializer import BookSerializer
from rest_frnamework.viewsets import ModelViewSet
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    
# serializer
from rest_framework import serializers
from .models import Book
class BookSerializer(serializer.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
  
# urls中
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('book',views.BookView,'books')

urlpatterns = [
    path('admin/',admin.site.urls),
]

# 两个列表相加  [1,2,4]+[6,7,8]
urlpatterns += router.urls

cbv源码分析

(一)

路由:path('api/v1/books/', views.BookView.as_view()),# 第二个参数无论是fbv还是cbv放的都是函数内存地址

1.当请求来了,匹配成功会执行 views.BookView.as_view()(request)
2.views.BookView.as_view()执行结果是View的类方法as_view,返回的结果是内层函数view,是个函数内层地址
3.本身请求来了,匹配成功,会执行view(request)
     #1.第一步
    def view(request, *args, **kwargs):
        return self.dispatch(request, *args, **kwargs)
    
    # 2.第二步 self.dispatch
    def dispatch(self, request, *args, **kwargs):
        
     
        # 3.request.method请求方式转成小写,必须在列表中才能往下走
        if request.method.lower() in self.http_method_names:
            # 4.反射,去self【视图类的对象:BookView】,去通过get字符串,反射出属性或方法
            # 5.BookView的get方法
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        # 5.BookView的get方法,加括号,传入request
        return handler(request, *args, **kwargs)


(二)

路由中:path('api/v1/books/', views.BookView.as_view())---》路由匹配成功就会执行---》views.BookView.as_view()(request)---->看一下BookView.as_view是怎么写的---》View这个类中的as_view类的绑定方法---》执行结果是view的内存地址[as_view中的内存函数,闭包函数]---》本质请求来了,执行view(request)--->return self.dispatch(request, *args, **kwargs)--->对象,谁的对象,View的对象,咱们从BookView---》View---》self是BookView的对象----》发现BookView没有dispatch---》View类的dispatch
    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() in self.http_method_names:
            # self是BookView的对象,通过字符串get找方法或属性,找到了get方法
            #handler就是BookView类的get方法
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        # 执行 BookView的get(request)---->get请求就会执行BookView的get方法,post请求就会执行BookView的post方法
        return handler(request, *args, **kwargs)
    

APIView执行内容(难)

  1. 基于APIView + JsonResponse编写接口

    APIView是基于django原生的View编写接口的,是drf提供给一个类(APIView),使用drf编写视图类,都是继承这个类及子类,APIView本身就是继承了Django原生的View

    from rest_framework.views import APIView #导入APIView
    from .models import Book
    from django.http import JsonResponse
    
    class BookView(APIView):
        def get(self,request):
            books=Book.objects.all()
            book_list=[]
            for book in books:
                book_list.append({'name':book.name,'price':book.price,'publish':book.publish})
             return JsonResponse(book_list,safe=False)
    

    json序列化列表,book_list是列表,想要序列化,需要将safe=False,

  2. 基于APIView + Response 写接口

    from rest_framework.views import APIView,Response
    from .models import Book
    
    class BookView(APIView):
        def get(self,request):
            books=Book.objects.all()
            book_list=[]
            for book in books:
                book_list.append({'name':book.name,'price':book.price,'publish':book.publish})
             return Response(book_list)  # 无论是列表还是字典都可以序列化
    
  3. APIView的执行流程

    分析

    路由中写的: path('books/', views.BookView.as_view()),

    -->>请求来了,执行views.BookView.as_view()() --->现在的as_viewAPIViewas_view

    # APIView的as_view方法:view还是原来的view,但是以后再也没有csrf认证了
    @classmehtod
    def as_view(cls,**initkwargs):
    	# 调用父类的as_view,父类是django原生的View
        # 把django原生View的as_view方法中的闭包函数view拿出来了
    	view = super().as_view(**initkwargs)
        # csrf_exempt排除所有的csrf的认证
        # 相当于在所有的方法上加上了这个装饰器
         return csrf_exempt(view)
        
    # 路由匹配成功,执行csrf_exempt(view)(request) -->View的as_view中的闭包函数view -->self.dispatch --->self(父类view方法产生的`self = cls(**initkwargs)`)是视图类的对象(BookView)产生 -->APIView的dispatch  
    def dispatch(self,request,*args,**kwargs): #APIView的dispatch  
        # request是django原生的request,原生request
        # 把原生request包装成新的request,这是drf提供的Request类的对象
        request= self.initialize_request(request,*args,**kwargs)
        # 从这里开始,出现的request都是drf提供的Request类的对象
        # 原生request是在request._request里面
        
        # 把新生的request放到了self对象【BookView的对象】
        self.request = request
        try:
            # 执行了三大认证【认证/频率/权限】,使用新的request,不读
            self.initial(request,*args,**kwargs)
            
            #反射出视图类【BookView】里面的方法
            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
    			# 把新的request传入了,视图类的方法中get的request也是新的
            response = handler(request, *args, **kwargs)
    
        except Exception as exc:
            # 在执行3大认证和视图类种方法的过程中,如果处理异常,都能捕获到(异常捕获是全局异常捕获)
            response = self.handle_exeception(exc)
        self.response = self.finalize_response(request,response,*args,**kwargs)
        return self.response
    

    总结

    APIView的执行流程:

    • 排除了所有csrf的认证
    • django中的原生request包装成drf提供的Request类 新的request,视图类中的requestRequest类的对象都是包装后的request。原生的request在新的request._request
    • 在执行视图类的方法之前,执行了3大认证
    • 如果在三大认证或者视图函数方法执行过程中出了错,会有异常捕获(异常捕获是全局异常捕获)
    • 以后视图类方法中的request都是新生的request

补充知识

装饰器的本质

# 装饰器
def auth(func):
    def outer(*args,**kwargs):
        res= func(*args,**kwargs)
        return res
    return outer

@auth  # 本质add=auth(add)
def add(): # 函数
    pass

# 使用auth装饰器装饰add函数,以后再使用add,其实就是在使用auth(add)的返回结果

Request对象源码分析(难)

区分原生request和新生request

原生request:django.core.handlers.wsgi.WSGIRequest

新生request:from rest_framework.request import Request

原生request可以在新生request._request中获取

Request源码

# 方法
1.__getattr__
   在视图类的方法中,执行request.method,新生的request是没有method的,就触发了新的Request的__getattr__方法的执行
    def __getattr__(self, attr):
        try:
            # 从老的request中反射出 要取得属性
            return getattr(self._request, attr)
        except AttributeError:
            return self.__getattribute__(attr)
2.request.data    包装了数据属性
    无论是post/put请求,放在了body中提交的数据,都是从request.data中取,取出来就是字典
    所有编码格式都可以
    
    
3.request.query_params    包装了数据属性
    get请求携带的参数,以后从这里取
    query_params:查询参数 ----->restful规范请求地址中带查询参数
 
4.request.FILES    包装了数据属性
     前端提交的文件,从request.FILES 取

Request类总结

  • 新生request跟之前用法一模一样,因为新的request取不到,会取原生request的__getattr__
  • request.data 无论什么编码,什么请求方式,只要是body中的数据,就从这里取出-->字典
  • request.query_params 就是原来的request._request.GET
  • 上传的文件从request.FILES

复习魔法方法

# 在类中,某种情况下会触发,会自动执行魔法方法
    __str__:打印对象会调用
    __init__:类()会调用
    __call__:对象()会调用
    __getattr__:对象点属性,如果属性不存在就会触发它的执行

前端不同的编码格式后端打印

urlencoded:    name=lqz&age=19&price=999 放在了请求体中
formdata:      分数据部分和文件部分
             '-------------------585520151165741599946333\r\n
             Content-Disposition: form-data; 
             name="name"\r\n\r\nlqz\r\n
             ------------------585520151165741599946333--\r\n'
        
json格式:   {"name":"lqz","age":19}

作业

# 1 使用ajax提交到后台数据
    ajax    urlencoded
            form-data
            json 
后台直接打印
   djang    request.body   

1.urlencoded

     $('#subBtn').click(function (){
         $.ajax({
             url:'',
             type:'post',
             date:{'username':$('#name').val(),'password':$('#password').val(),'csrfmiddlewaretoken':'{{ csrf_token }}'},
             success:function (args){

            }
         })

     })

2.form-data
添加表头

 <form action="" method="post" enctype="multipart/form-data">
  <script>
     $('#subBtn').click(function (){
         $.ajax({
             url:'',
             type:'post',

             date:{'username':$('#name').val(),'password':$('#password').val(),'csrfmiddlewaretoken':'{{ csrf_token }}'},
            contentType:false,
             processData:false,// 使用form_data交互
             success:function (args){

            }
         })

     })
 </script>

3.json

$('#d1').click(function)(){
    $.ajax({
        url:'',
        type:'post',
        data:JSON.stringify({'name':'kimi','age':18}),//千万要写真实的数据
        contentType:'application/json',
        success:funcion (args){
            alert(args)
        }
    })
}
</script>

问题总结:
1.使用pycharm打开sqlite的问题
sqlite文件,文件形式可能是文本模式或是其他形式(xx.mp4,xx.txt),但是他们的本质是一样的,只是打开的方式/编辑器不同而呈现不同的效果。

    如果我们首次打开它选择了txt,之后打开的都是txt,如何解决?
     1.使用navicate编辑器打开并编辑,不用pycharm编辑器
     2.使用pycharm正常连接sqlite(同链接mysql)

2.模型表的改动都需要重新迁移数据,但如果改动了模型的表名,迁移了数据库,但是sqlite数据库的表名还是没变,如何操作?

    1.删除了数据库sqlite
    2.在app01下的文件migrations下的initial.py文件,如下图

image

drf的思维导图

image

posted @ 2023-01-30 16:22  魔女宅急便  阅读(101)  评论(0)    收藏  举报
Title