栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django 基础(1)-快速入手写代码(项目结构、开发流程、视图、视图集)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django 基础(1)-快速入手写代码(项目结构、开发流程、视图、视图集)

文章目录
  • 一、Django 基础
    • 1. django 项目的目录结构
    • 2. Pycharm 启动django
      • 1)python解释器是远程情况处理(重要)
    • 3. django一般开发流程
      • 1) 定义 URL
        • 理解urls路由 urls.py
      • 2) 视图View的编写
        • 视图添加 csrf_exempt,支持被跨域访问
      • 3)django 配置数据库
      • 4)Django 终端打印SQL语句
      • 5)django objects数据库相关操作
        • Django中object.all是什么东西
        • django ORM: 通过Model类来操作数据库
  • 二、视图、视图集(重要)
    • 1. APIView
      • 1.1 View与APIView的区别
    • 2. ViewSets、ReadOnlyModelViewSet
        • django启动报错has no attribute get_extra_actions
      • ReadOnlyModelViewSet
    • 3. (重要)ModelViewSet视图
      • 自定义action
      • Django的rest_framework的序列化组件之serializers.ModelSerializer
    • 4. GenericViewSet 视图集
    • 5. django基类View.as_view()
  • 三、常见基础问题整理
    • 关于 manage.py.
    • pycharm创建的django项目,启动报错:TypeError: unsupported operand type(s) for /: 'str' and 'str'
    • 请求接口,报错Forbidden (CSRF cookie not set.)

一、Django 基础 1. django 项目的目录结构

我们使用pycharm创建一个django项目:
一般django 项目目录结构

如下,默认的新建的文件如下:

  • urls.py
    urls.py本质上就是一个标准的python文件,这个python文件的作用就是在URL请求和处理该请求的视图函数之间建立一个对应关系,换句话说,它就是一个url请求映射表。
    除了在项目根目录下有一个urls.py之外,项目的每个应用下都会有一个urls.py配置文件。

    urls.py 决定了哪个请求由哪个函数来处理

  • manage.py
    新建一个django项目,都会产生manage.py的文件。manage.py是在创建每个Django project时自动添加在项目目录下的,其功能是将Django project放到sys.path目录中,同时设置DJANGO_SETTINGS_MODULE环境变量为当前project的setting.py文件。

    #!/usr/bin/env python
    import os
    import sys
    
    if __name__ == "__main__":
        # 设置环境变量DJANGO_SETTINGS_MODULE,值为djangoProject1.settings,即django项目的settings.py所在路径
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoProject1.settings")
        try:
            from django.core.management import execute_from_command_line
        except importError:
            # The above import may fail for some other reason. Ensure that the
            # issue is really that Django is missing to avoid masking other
            # exceptions on Python 2.
            try:
                import django
            except importError:
                raise importError(
                    "Couldn't import Django. Are you sure it's installed and "
                    "available on your PYTHonPATH environment variable? Did you "
                    "forget to activate a virtual environment?"
                )
            raise
        # 执行命令  sys.argv值为 ['F:/work_code/djangoProject1/manage.py', 'runserver', '8000']
        execute_from_command_line(sys.argv)
    
  • venv目录
    要使用django,首先需要建立一个虚拟工作环境,在这个虚拟工作环境中可以安装包,将其与其他项目隔离,主要解决Python软件开发过程中版本与依赖性问题以使得每个项目有自己独立的安装目录。

2. Pycharm 启动django
  1. 先打开mange.py,然后再运行,会提示一堆东西,表示没有配置参数。在pycharm中
    点击edit configurations 编辑配置参数。
    2.点开之后弹出如下对话框,在scrip parameters 对应的对话框中输入配置参数 runserver 127.0.0.1:8000 或 runserver 0.0.0.0:8000 配置完成之后点击ok就完成了。
1)python解释器是远程情况处理(重要)

场景:一般情况下,我们的web后台还是运行在linux环境下,我们需要使用远程python解释器,让真实代码运行在远端。

解决方法:
1) 给项目配置远程python解释器

注意:上图的path mappings比较重要,是你本地代码和远端linux代码目录映射关系。一定留意进行配置。Pychram启动Django项目时,会上传代码到该指定目录。

2) 点击edit configurations 编辑配置参数。
如之前一样,如下图,配置 启动参数即可。

3) 自动同步配置(重要)
该步骤非常重要,虽然我们第一步配置了 本地和远端的映射,当我们Pycharm配置的多个远端时,只有一个自动上传生效,我们需要配置确认,切换项目时,自己手动切换。

选择Tool -> Deployment,如下:

确认您当前的自动上传配置选项!

3. django一般开发流程

Django 使用 MVC/MTV 模式,其本质是为了保持各组件之间松耦合关系。

  • Model(模型):负责业务对象与数据库的对象(ORM)
  • Template(模版):负责如何把页面展示给用户
  • View(视图):负责业务逻辑,并在适当的时候调用 Model 和 Template
    此外,Django 还有一个 url 分发器,它的作用是将一个个的 URL 页面请求分发给不同的 view 请求, view 再调用相应的 Model 和 Template 。

用户访问,首先通过urls进行访问路径的匹配,然后转到匹配到的方法或函数,转到 views 进行逻辑处理。
若需要访问数据库,则通过 models 访问数据库,获取需要的数据,返回给 views。
views 处理完成后,若是API调用方式,直接返回数据给用户;否则通过 template 对指定的模板进行渲染,然后将对应的 html 返回给页面。

1) 定义 URL

Django学习–urls.py详解
参考URL: https://www.cnblogs.com/hskullbk/p/9216343.html

urls.py:又称为URL分发器(路由配置文件)
url配置格式:

    urlpatterns = patterns('视图前缀',  
        url(r'^正则表达式1/$', '视图函数1', name="url标识1"),  
        url(r'^正则表达式2/$', '视图函数2', name="url标识2"),  
    )  

注意:

  • url函数的第二个参数,表示视图函数,它的名字不是随便取的,必须要在views.py中真实存在,项目的每个应用下都会有一个views.py文件。
  • views.py文件中的视图函数,其第一个参数必须是HttpRequest对象。
  • name的作用主要体现在一个视图函数对应多个url请求的场景中,name可以用来唯一标识一个url,所以它必须全局唯一
理解urls路由 urls.py
from django.conf.urls import url
from django.contrib import admin
from demo import views  # 此处需要import

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/$', views.login),  # 此处第一个参数是正则匹配,第二个参数是对应的方法或者函数
]
2) 视图View的编写

Django的View(视图)
参考URL: https://www.cnblogs.com/wangkun122/p/8312767.html
视图View的编写
参考URL: https://blog.csdn.net/weixin_42134789/article/details/80311325
django类视图as_view()方法解析
参考URL: https://www.cnblogs.com/olivertian/p/11072528.html

Django使用请求和响应对象来通过系统传递状态。

当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。

视图添加 csrf_exempt,支持被跨域访问

在Django中对于基于函数的视图我们可以 @csrf_exempt 注解来标识一个视图可以被跨域访问。那么对于基于类的视图,我们应该怎么办呢?

简单来说可以有两种访问来解决
方法一:在类的 dispatch 方法上使用 @csrf_exempt

from django.views.decorators.csrf import csrf_exempt

class MyView(View):

    def get(self, request):
        return HttpResponse("hi")

    def post(self, request):
        return HttpResponse("hi")

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(MyView, self).dispatch(*args, **kwargs)

方法二:在 urls.py 中配置

from django.conf.urls import url
from django.views.decorators.csrf import csrf_exempt
import views

urlpatterns = [
    url(r'^myview/$', csrf_exempt(views.MyView.as_view()), name='myview'),
]

常用,需掌握!

3)django 配置数据库

settings.py

pg数据库:

DATAbaseS = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'db_name',                      
        'USER': 'db_user',
        'PASSWORD': 'db_user_password',
        'HOST': '',
        'PORT': 'db_port_number',
    }
}

pip install psycopg2

注意需要安装psycopg2
否则启动django就会报错:
django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: No module named psycopg2

mysql数据库:

DATAbaseS = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': DB_HOST,
        'USER': DB_USER,
        'NAME': DB_NAME,
        'PORT': '{}'.format(DB_PORT),
        'PASSWORD': DB_PWD,
        'OPTIONS': {
            'charset': 'utf8mb4'
            },
    }
}

pip install mysql-python
在 python2 中,使用 pip install mysql-python 进行安装连接MySQL的库,使用时 import MySQLdb 进行使用;
python2.x使用MySQLdb,python3.x使用PyMysql模块。
pip install pymysq

4)Django 终端打印SQL语句

以下配置写到 settings.py内即可

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
    'console': {
        'level': 'DEBUG',
        'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level': 'DEBUG',
        },
    }
}

5)django objects数据库相关操作

Django数据库相关操作
参考URL: https://blog.csdn.net/weixin_42223833/article/details/88978911
Django数据库操作语句
参考URL: https://www.pianshen.com/article/6823334375/

查询
types = Type.objects.all() #查询所有类型

删:

# 删除单条
t = Type.objects.get(id = 8)
t.delete()
# 删除多条
t = Type.objects.filter(label = "小说")
t.delete()

添加
models.UserInfo.objects.create(username=‘andy’,password=‘123456’,age=33)

在Django中定义数据库表,并使用Django提供的方法来对数据库进行操作(增、删、改、查)

1、定义3个数据库表:
 1 class Group(models.Model):
 2     name = models.CharField(max_length=50,default=None)
 3 
 4 class User(models.Model):
 5     name = models.CharField(max_length=50,default=None)
 6     Email = models.CharField(max_length=50,default=None)
 7 
 8     group_relation = models.ManyToManyField(‘Group‘,default=None)   #生成多对多表
 9 
10 class Asset(models.Model):
11     hostname = models.CharField(max_length=50,default=None)
12     create_date = models.DateTimeField(auto_now_add=True)
13     update_date = models.DateTimeField(auto_now=True)

2、向数据库中添加内容
1 Asset.objects.create(hostname=name)
2 
3 #多对多添加数据
4 u1 = User.objects.filter(id=1)
5 g1 = Group.objects.filter(id=1)
6 u1.group_relation.add(g1)
7 g1.user_set.add(u1)

3、从数据库中删除内容
1     Asset.objects.get(id=id).delete()
2 
3     # 多对多删除数据
4     u1 = User.objects.filter(id=1)
5     g1 = Group.objects.filter(id=1)
6     u1.group_relation.delete(g1)
7     g1.user_set.delete(u1)

4、修改数据库中的内容
1     #根据id修改hostname
2     obj = Asset.objects.get(id=id)
3     obj.hostname=hostname
4     obj.save()
5 
6     #所有id大于传入参数的,就将hostname修改
7     Asset.objects.filter(id__gt=id).update(hostname=hostname)

5、查询数据库中的内容
 1     # 多对多获取数据
 2     u1 = User.objects.filter(id=1)
 3     g1 = Group.objects.filter(id=1)
 4     u1.group_relation.all()
 5     u1.group_relation.all().filter(id=1)
 6     g1.user_set.all()
 7     g1.user_set.all().filter(email=‘‘)
 8 
 9     #查找所有id大于传入参数的数据
10     Asset.objects.filter(id__gt=id)
11     #查找所有hostname包含传入参数的数据
12     Asset.objects.filter(hostname__contains=hostname)
13     #查找类型id等于5的所有用户信息---type__id:type表示UserInfo表中的type字段(对应type表的外键),__id表示与userinfo表相关联的type表的id
14     UserIfo.objects.filter(type__id = 5)
15     #取出所有数据
16     Asset.objects.all()
17     #取出所有数据的前两条数据
18     Asset.objects.all()[0:2]
19     # 取出所有数据,并进行排序---id:按id正序排列,倒序就用‘-id‘
20     Asset.objects.all().order_by(‘id‘)
21     # 取出所有数据中的id和hostname列数据
22     Asset.objects.all().values(‘id‘,‘hostname‘)

基础,必须掌握!

Django中object.all是什么东西

Django中object.all是什么东西
参考URL: https://www.cnblogs.com/chaojiyingxiong/p/9703609.html

在django中的view.py中,我们可能回经常见到 book_set= Book.objects.all(),book_list = Book.objects.get()?

让我们疑惑的问题是,objects是个什么东西,book_set 和book_list 又是个神马东西?

object是Manager类型的对象,定义在from django.db import models中,是默认生成的,也就是objects = Modes.Manage() 。用途是数据库和模型对象交互的接口(api)。book_set返回的是个集合,book_list返回的是个列表。book = Book.objects.all(),这个翻译成银行得话就是,一个叫BOOK得人来到银行,通过一个名叫objects得柜员,查询BOOK得银行余额和银行卡信息,结果得到一个queryset对象

在book =BOOK.objects.get()或者book = BOOK.objects.all()中

在book =BOOK.objects.get()或者book = BOOK.objects.all()中

  • BOOK是类名,就是你在model中创建的类
  • objects是django默认的管理器对象,就是刚才的比喻中的银行柜员,帮你完成各种操作。
  • get()或者all()是API,一种内置函数,也就是比喻钟银行柜员可以帮助我们完成的各种具体业务,不同的业务调用不同的API就可以了。
  • book通过all()得到的就是要给queryset()对象,也就是查询对象集合。
django ORM: 通过Model类来操作数据库

Django是通过Model类来操作数据库的,程序员不需要关注SQL语句和数据库的类型(无论数据库是MySql、Sqlite,还是其它类型),Django自动生成相应数据库类型的SQL语句,来完成对数据库数据的操作。

model是对于信息的一种模型封装与定义。它包含了你要存储的必要字段和操作数据的方法。一句话概括就是,每个模型映射了一张数据表。

每个model都是继承于django.db.models.Model 的Python类。

简单实例
这个例子定义了Person ,并给它赋予了first_name 和last_name:

其中first_name 和last_name 是model的字段。如你所见,每一个字段被定义为class类的一个属性,而每个属性对应着数据库的一列。

自动主键字段
默认情况下,Django给每个模型以下字段:

这是一个自动添加的自增主键。
如果你想声明一个典型的主键,只需要在对应的字段选项中设置primary_key=True。若Django看到你显式声明了自定义的主键,那么Django就不会为你创建一个自增的id字段。
每个模型需要明确一个字段作为主键。

二、视图、视图集(重要)

drf中的各种view,viewset
参考URL: https://www.cnblogs.com/hehecat/p/9349427.html

Django REST framework里有各种各样的view。
如上图所示,View类是Django本身的东西,剩下的都是django rest framework的东西!

Django用“视图”这个概念封装处理用户请求并返回响应的逻辑。

视图是一个可调用对象,它不仅可以是基于函数,也可以是基于类的。

相比较与函数,基于类的视图有一些区别和优势:

  • 组织与特定HTTP方法相关的代码(GET,POST等) 可以通过单独的方法而不是条件分支来解决。
  • 面向对象的技术例如Mixin(多继承、混用)可以将代码分解成可重用的组件。

视图函数:

def my_view(request):
    if request.method == 'GET':
        # 
        return HttpResponse('result')

视图类:

class MyView(View):
    def get(self, request):
        # 
        return HttpResponse('result')

Django中的View是所有基于类的view的父类,它负责将视图连接到URL、HTTP 方法调度(GET,POST等)和其它简单的功能。

总结: drf框架自带的视图集有ViewSet,GenericAPIViewSet,ModelsViewSet,ReadOnlyViewSet.视图集的核心是基于action而非直接的请求方式(post,get)等将请求和视图方法进行绑定,其基于ViewSetMixin类来实现。其他的视图集都是基于此类与××View的扩展。**ViewSet视图集不带任何action,只是封装了response,request来满足用户的各种请求格式。**另增加了鉴权,限流,认证等功能。GenericAPIViewSet视图集自带了queryset和serializer_class及相关的方法。**ModelsViewSet封装了增删改查列表5种常用的请求动作。**ReadOnlyViewSet封装了list和retrieve两种请求动作,方便用户查阅。

1. APIView

View是Django默认的视图基类,APIView是REST framework提供的所有视图的基类, 继承自Django的View。

APIView与View的不同之处在于:

  • 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
  • 视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
  • 任何APIException异常都会被捕获到,并且处理成合适的响应信息;APIException异常捕获
  • 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。

REST framework的APIView继承了django的View,部分源码如下

class APIView(View):
# The following policies may be set at either globally, or per-view.
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
metadata_class = api_settings.DEFAULT_metaDATA_CLASS
versioning_class = api_settings.DEFAULT_VERSIONING_CLASS

APIView多了一些属性和方法,比如:身份认证、权限检查、流量控制

  • authentication_classes 身份认证
  • permission_classes 权限检查
  • throttle_classes 流量控制
1.1 View与APIView的区别

View是Django默认的视图基类,APIView是REST framework提供的所有视图的基类, 继承自Django的View。

APIView与View的不同之处在于:

  • 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
  • 视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
  • 任何APIException异常都会被捕获到,并且处理成合适的响应信息;APIException异常捕获
  • 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
2. ViewSets、ReadonlyModelViewSet

Django编写RESTful API(六):ViewSets和Routers
参考URL: https://www.cnblogs.com/zivwong/p/7472219.html

ViewSets,翻译过来可以说是视图集,也就是几个视图的集合。从单词上看,view 视图 set 集合,viewset就是视图的集合。只是用了新的封装,Django 的view中的东西依然可以用。

它的抽象程度更高,也可以说是代码量又减少了。

ViewSet类与View类其实几乎是相同的,不提供任何方法处理函数,如get()或post()
它有一些动作,比如“list()”、“retrieve()”(检索)、“create()”等等。动作只在实例化视图的时候绑定到方法。 viewset自动提供了list, create, retrieve, update 和 destroy 动作.

我们平时使用视图类的时候,编写urls.py时,就一个XXX.as_view(),现在使用ViewSets,大概像下面这样的:

user_list = UserViewSet.as_view({'get': 'list'})
user_detail = UserViewSet.as_view({'get': 'retrieve'})

自己添加额外的动作,要记得在方法前面加上装饰器@detail_route,这个装饰器就是用来创建自定义的动作,当然我们的自定义动作不可以是create/update/delete这些标准的,否则会有冲突。

还有一点,用**@detail_route装饰器定义的动作默认是GET请求**,需要其他的请求方式可以传入methods参数给这个装饰器。同样的,默认情况下,自定义操作的URL取决于方法名称本身。如果要更改url应该构造的方式,可以将url_path作为decorator的关键字参数。

使用场景:
举个例子,我们之前查看所有用户列表就要写一个视图类UserList,并在urls.py中为其设置一个模式然后as_view使用它,然后要看单个用户的详情页就要再写一个UserDetail视图类并再在添加一个url模式。
同时注意到这两个视图类都是继承的generics.XXXAPIView。而使用ViewSets我们就可以把UserList和UserDetail合并成UserViewSet视图类,并且继承的类改为viewsets.ReadOnlyModelViewSet,这样就是一个视图集了。

django启动报错has no attribute get_extra_actions

使用router方式配置url,ProjectAPIView需要继承ViewSet
不然报错

总结: 你要用 router.register 这种方式写路由,你的对应的view类就必须至少继承 ViewSet,都是以ViewSet为基础。否则你就写成类似 如 url(r’^login/$’, views.LoginView.as_view(), name=“login”), 形式。

实例demo如下:

urlpatterns = [
    url(r'^logout/$', views.logout, name="logout"),
    url(r'^login/$', views.LoginView.as_view(), name="login"),
]

router = routers.SimpleRouter()
router.register(r'xxx', views.XxxViewSet, basename='xxx')

urlpatterns += router.urls
ReadonlyModelViewSet

ReadonlyModelViewSet(mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet)
一个提供默认“列表()”和“检索()”操作的viewset。

3. (重要)ModelViewSet视图

ModelViewSet基础讲解(纯干货)
参考URL: https://blog.csdn.net/God_Hearing/article/details/108874433
django-ModelViewSetv
参考URL: https://www.cnblogs.com/kkxb/p/13747139.html

rest-framework 允许将一组相关逻辑的视图组合在同一个视图类中, 叫做视图集(viewset).
一个视图集只提供行为(action) 例如list和create, 不提供任何处理函数 (handler) 例如get或post.

视图集的处理函数需要通过在 as_view() 方法中传入映射字典对各个处理函数和行为进行映射.
(注: viewset 的 as_view() 方法已重写, 可以接收一个字典作为参数, 完成行为和处理方法之间的绑定)

ModelViewSet(mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin, mixins.ListModelMixin,GenericViewSet)
一个提供默认“create()”、“检索()”、“更新()”,“部分更新()”、“销毁()”和“列表()”操作的viewset。

ModelViewSet是封装度最高的DRF的视图类。包含了增删改查中的所有接口操作。

它继承自GenericViewSet、ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

注意,因为继承关系,必须在内部定义属性,queryset和serializer_class,因此,ModelViewSet通常结合ModelSerializer使用

功能
1.认证 (登录认证)
2.权限 (规定用户的可操作范围)
3.限流 (限制接口访问速度)
4.分页
5.序列化 (返回json)
6.过滤 ()
7.排序 (ordering=-id)
8.版本 (接口版本号,用v1/v2/v3)

使用视图集,可以将一系列逻辑相关的动作放到一个类中:

  • list() 提供一组数据
  • retrieve() 提供单个数据
  • create() 创建数据
  • update() 更新数据
  • destory() 删除数据

视图集类不再实现get()、post()、put()、delete()方法,而是实现动作 action。 如 list()、retrieve()、create()、update()、destory()


经过测试,我们的view类继承了ModelViewSet后,直接使用上面类似的 http url,增删改查,就自动有了增删改查的能力。django rest framework的ModelViewSet非常爽,省了一大堆业务逻辑代码

#views中
class BookInfoViewSet(ModelViewSet):
    """增删改查图书信息"""

    # 指定查询集
    queryset = BookInfo.objects.all()
    # 指定序列化器
    serializer_class = BookInfoModelSerializer

我们在视图类中,要 指定查询集、指定序列化器

定义好了API视图后,需要在路由中,将请求方法与action进行绑定

from django.conf.urls import url
from django.urls import path,include
from . import views
#导入路由控制类
from rest_framework.routers import SimpleRouter,DefaultRouter

#实例化路由控制对象
router = DefaultRouter()
#注册
router.register(r'book',views.BookInfoViewSet)

#编写路由,固定写法,不清楚是否还有其他写法
urlpatterns = [
    url(r'',include(router.urls)),
]
自定义action

官网: https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions

detail_route和detail_list将在DRF 3.0上被弃用,而使用@action:

  • 使用action装饰器
  • methods
  • 支持的请求方式,为一个列表,默认为[‘get‘]
  • detail
    • 必传参数,
    • 要处理的是否是详情资源对象(即是否通过url路径获取主键)
    • True表示需要传递主键id,使用通过URL获取的主键对应的数据对象
    • False表示不需要传递主键id,不使用URL获取主键
  • url_path
    • 指定url部分,默认为action名称
  • url_name
    • 指定url的名称,默认为action名称

总结: method:请求方式, detail:是否带pk。 detail,必传参数,要处理的是否是详情资源对象(即是否通过url路径获取主键),True表示需要传递主键id,使用通过URL获取的主键对应的数据对象,False表示不需要传递主键id,不使用URL获取主键。

action装饰器可以接收两个参数:

  • methods: 声明该action对应的请求方式,列表传递
  • detail: 声明该action的路径是否与单一资源对应,及是否是xxx//action方法名/
    • True 表示路径格式是xxx//action方法名/
    • False 表示路径格式是xxx/action方法名/

如上,亲测可用! 工作中按需配置 detail 为true或false。

Django的rest_framework的序列化组件之serializers.ModelSerializer

Django的rest_framework的序列化组件之serializers.ModelSerializer介绍
参考URL: https://www.cnblogs.com/bainianminguo/p/10448013.html
一起自学DJANGO:4.使用MODELSERIALIZERS写序列化器
参考URL: https://www.freesion.com/article/5135788072/

django的rest_framework的一大特色是序列化器,其封装了视图中关于用户请求,验证及响应数据的处理部分,使得程序简洁化。
serializers.ModelSerializer如下几个功能
1、序列化queryset数据
2、反序列化json数据,将反序列化后的数据转换成model对象
3、反序列化的时候还是可以对数据做校验
4、如果合法,可以调用sava方法进行post或者put请求操作
5、如果不合法,则返回错误

#从rest_framework框架导入serializers内含ModelSerializer类
from rest_framework import serializers
#从shops应用模块下的models导入Bshop表单模型
from shops.models import Bshop

#class 表单模型名+Serializer(serializers.ModelSerializer):
class BshopSerializer(serializers.ModelSerializer):
    class meta:
        model = Bshop
        fields = ['num','name','where','near','puttime','changetime']

测试验证,打开控制台

#从commoditys应用模块下的serializers导入CommoditySerializer序列化器
from goods.serializers import BgoodSerializer
#            表单模型名+Serializer
serializer = BgoodSerializer()
print(repr(serializer))

测试成功,在指令发出去之后,我们写好的Bgood表单模型就会被调用,exit()退出

4. GenericViewSet 视图集

官方源码:

class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    """
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    """
    pass

GenericViewSet 继承自 GenericAPIView ,并且添加了一个 ViewSetMixin ,而 ViewSetMixin 实现了 as_view ,而 GenericAPIView 本身没有定义 action,没有定义 get 和 post 等方法

5. django基类View.as_view()

django基类View.as_view()
参考URL: https://www.cnblogs.com/Undo-self-blog/p/9146323.html

url中使用了as_view()方法后,返回的闭包会根据请求的方式到对应的视图函数中找以请求方式命名的函数进行执行。
而传统的url中不使用as_view()方法,则直接执行对应视图函数,和请求方法没有关系。

一般请求的判断方法:

def view(request, *args, **kwargs):
    if request.method.lower() == 'get':
        do_something()
    if request.method.lower() == 'post':
        do_something()

使用View.as_view()代替判断:

class ClassName(View):
    '''
    继承View自动判断请求方法
    '''
    def post():
        pass

    def get():
        pass

    def other():
        pass

#调用方法
url(url, ClassName.as_view(), name)

三、常见基础问题整理 关于 manage.py.

flask框架,没有manage.py.
django框架才有。

pycharm创建的django项目,启动报错:TypeError: unsupported operand type(s) for /: ‘str’ and ‘str’

这是由于自动生成的代码中存在语法错误(在settings.py中的错误代码为 ‘DIRS’: [base_DIR / ‘templates’]),将其修改为 ‘DIRS’: [str.format(base_DIR, ‘/templates’)]

请求接口,报错Forbidden (CSRF cookie not set.)

这是因为Django对表单post请求做的安全性验证,在app开发中,可以干掉这一项,具体操作如下:

修改settings.py文件,注释掉
django.middleware.csrf.CsrfViewMiddleware’

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XframeOptionsMiddleware',
]
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/487622.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号