- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想了解如何使用Django DRF进行注册:
请说明使用 ViewSet 和泛型的差异。
这些是我的尝试。
我来自Flask,发现使用装饰器定义多个端点非常清晰。
@application.route('/people/', endpoint='people')
def people():
# return a list of people
pass
@application.route('/last/', endpoint='last_person')
def last_person():
# return last person
pass
@application.route('/people/', endpoint='people')
def people():
field = request.args.get('last', None)
if field:
# return last person from list of people
else:
# return list of people
我了解 DRF 的好处可能是一致性并阅读了文档,但发现比较麻烦,希望更清楚地了解如何利用ModelsViewSets和Generics来看看VS Flask的好处。
请提供一个示例来获取用户列表和最后一个用户。
<小时/># serializer.py
from rest_framework import serializers
from .models import Person
class PersonSerializer( serializers.HyperlinkedModelSerializer):
class Meta:
model = Person
fields = ('name', 'nickname', 'timestamp')
# views.py
class PersonViewSet( viewsets.ModelViewSet):
queryset = Person.objects.all().order_by('name')
serializer_class = PersonSerializer
我理解类 PersonViewSet
应该准备好公开方法来获取列表以及检索项目,因为 ModelViewSet
: https://www.django-rest-framework.org/api-guide/viewsets/#modelviewset
但是在注册端点时如何明确地看到这一点?
示例:
# urls.py
router = routers.DefaultRouter()
router.register(r'people', views.PersonViewSet)
app_name = 'myapi'
urlpatterns = [
path('', include(router.urls)),
]
当我浏览 http://127.0.0.1:8000/api/
时,我只能看到一个端点。是的,如果我尝试 http://127.0.0.1:8000/api/1/
它会自行检索用户,但是我如何在上面的代码中读取它?如何从 PersonViewSet
映射一个方法(例如 PersonViewSet.get_last_person()
)来指示使用相同的端点来获取最后一个条目?
我读到 Generics
模型公开了适合检索单个项目而不是列表的 API 模型:
https://www.django-rest-framework.org/api-guide/generic-views/#retrieveapiview
我尝试在views.py
中添加:
# I make use of RetrieveAPIView now
class LastPersonView( generics.RetrieveAPIView):
queryset = Person.objects.all()
serializer_class = PersonSerializer
和urls.py
中:
router.register(r'people', views.PersonViewSet)
router.register(r'last-person', views.LastPersonView)
但这会产生错误:AttributeError:类型对象“LastPersonView”没有属性“get_extra_actions”因为 Generics 没有 get_extra_actions ,比如 ViewSet
在第二个示例中,如何在我的路由器中注册两个 View ?
https://stackoverflow.com/a/40759051/305883
我还可以通过分配基本名称来指示 ViewSet 在我的 urls.py
中注册不同的端点:
router.register(r'people', views.PersonViewSet)
router.register(r'last-person', views.PersonViewSet, basename='lastperson')
并使用相同的ModelViewSet
:
class PersonViewSet( viewsets.ModelViewSet):
queryset = Person.objects.all().order_by('name')
serializer_class = PersonSerializer
我知道这种方法的好处是更“简单”,因为查询集总是相同的。
但是我可以注册一个方法来检索最后一个对象,并将该方法映射到我的路由器中(include(router.urls)
)吗?
可以提供使用 ModelViewSets、泛型和更明确的方法的示例,在 View 中声明方法并在端点中调用这些方法吗?
您能否说明哪种方法可能更好:
最佳答案
我将详细介绍您所采取的每种方法,并提供一个解决方案来满足您基于该方法的需求。那么让我们开始吧...
<小时/>您的第一种方法:
您的第一种方法使用非常典型的 DRF 设置,并为 PersonViewSet
的各种操作生成路由。由 DRF 本身提供。
现在,您需要添加一个新的 URL 端点,该端点将解析为 queryset
的最后一个对象。 :
Person.objects.all().order_by('name')
据推测,端点应位于 person
下基本名称。
我们可以利用action
这里的装饰器将 HTTP GET 映射到要映射到 View 集中的某个方法的某个 URL,并且从该方法我们可以设置 kwargs
要设置的 View 集实例的属性 pk
到最后一个对象,最后将请求发送到retrieve
方法本身例如:
from rest_framework.decorators import action
class PersonViewSet(viewsets.ModelViewSet):
queryset = Person.objects.all().order_by('name')
serializer_class = PersonSerializer
@action(
methods=['get'],
detail=False,
url_path='last',
url_name='last',
)
def get_last_person(self, request, *args, **kwargs):
last_pk = self.queryset.all().last().pk
self.kwargs.update(pk=last_pk)
return self.retrieve(request, *args, **kwargs)
现在,如果您请求/people/last/
端点,您将获得最后检索到的对象的响应。
请注意,如果您有 lookup_url_kwargs
和lookup_field
不同于pk
,您需要使用 kwargs
中的设置正如你所想象的那样。另外,您可以对 retrieve
进行操作你自己而不是委托(delegate)给 retrieve
但让我们保持干燥。
FWIW,如果您也想使用此端点进行 PUT/PATCH/DELETE,则需要添加 action
中的方法并根据方法名称将它们委托(delegate)给相应的操作。
第二种方法:
View 不是 ViewSet(查看两者的基类: rest_framework.views.View
和 rest_framework.viewsets.ViewSet
); DRF 路由器为 View 集而不是 View 创建端点。有多种方法可以将 View 转换为 View 集,基本上只需继承 viewsets.GenericViewSet
即可。 -- 它继承自 viewsets.ViewSetMixin
和generics.GenericAPIView
.
viewsets.ViewSetMixin
通过在 as_view
中提供所有必要的操作方法映射,具有将 View 转换为 View 集的实际魔力类方法。
为了使这种方法发挥作用,我们需要定义一个 retrieve
从序列化器发送响应的方法:
from rest_framework import generics
from rest_framework.response import Response
class LastPersonView(generics.RetrieveAPIView):
serializer_class = PersonSerializer
queryset = Person.objects.all().order_by('name')
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.all().last()
serializer = self.get_serializer(instance)
return Response(serializer.data)
generics.RetrieveAPIView
的get
方法将请求委托(delegate)给 retrieve
因此我们重写了 retrieve
方法在这里。
现在,我们需要将路由定义为常规端点,而不是在 DRF 路由器中:
urlpatterns = router.urls + [
path('last-person/', LastPersonView.as_view()),
]
<小时/>
第三种方法:
您已经为同一 View 集注册了两个不同的前缀(这里再次使用 View 不起作用,必须是 View 集),因此两组不同的 URL 映射具有所有相同的 CRUD 操作。根据您的期望,我认为这不是您想要的,因此我不会进一步讨论这种方法,但我认为您从上面已经明白为什么它不相关了。
<小时/>现在,如果我必须选择,我会更喜欢第一种方法,因为所有内容都在相同的 View 集、前缀和基本名称下,并且您不需要乱搞 URLConf。
我希望以上内容能澄清一两件事。
关于python - 在 Django DRF 中注册多个路由 - 使用和调用 ModelViewSets 或 Generics 中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59006970/
背景 我有一个定义了多个自定义操作的 ModelViewSet。我在 urls.py 中使用默认路由器注册 URL。现在,我的 View 使用默认创建的路由,如 ^images/$ , ^images
DRF 中的 request.data 和 DRF 中的 serializers.data 有什么区别。 当我在 DRF 中编写基于函数的 View 时,我会像使用它们一样 - eli
我用Django REST框架准备了API。我正在使用docker运行我的API,一切在我的机器上都运行得很好。因此,我只需运行docker-compose up,就可以在浏览器中使用Swagger测
我用Django REST框架准备了API。我正在使用docker运行我的API,一切在我的机器上都运行得很好。因此,我只需运行docker-compose up,就可以在浏览器中使用Swagger测
快速上手JWT签发token和认证,有这一篇就够了,DRF自带的和自定义的都帮你总结好了,拿去用~ DRF JWT认证(二) 上篇中对JWT有了基本的认知,这篇来略谈JWT的使用 签发:一般我们登录成
什么接口文档都不用手写了?自动挡? DRF 自动生成接口文档 我们知道前后端分离,前端一般按后端写好的接口去开发,那么就需要我们明细后端接口数据等,需要写接口文档,前端按照接口文档去开发 接口文档如何
为什么要使用JWT认证?构成和原理又是什么?怎么还有Base64的事?我都写了👆 DRF JWT认证(一) JWT认证 Json web token (JWT), 是为了在网络应用环境间传递声明而执
DRF 中如何使用过滤,排序,分页,以及报错了如何处理?10分钟get了~ DRF 过滤排序分页异常处理 过滤 涉及到查询数据的接口才需要过滤功能 DRF过滤使用种类: 内置过滤类 第三方 自定义 内
前后端分离开发怎么给接口做认证权限频率三大认证?点进来5分钟get! DRF-认证权限频率 前后端混合开发,可以通过HttpResponse对象来设置cookie进而校验登录,现在前后端分离开发,用不
你问我使用DRF视图组件快速写接口?九九归一剑诀早就准备好了,没有副作用! DRF 视图组件 DRF框架提供了很多通用的视图基类与扩展类,上篇使用的APIView是比较偏Base的,视图的使用更加简化
1、路由Routers 在 Rest Framework 中提供了两个 router , 可以帮助我们快速的实现路由的自动生成。 必须是继承 ModelViewSet 的视图类才能自动生成路由
1. 前言 大家好,我是安果! 接下来,将通过几篇文章将对 DRF 模型序列化进行展开说明,详情谈谈模型序列化的作用、步骤及进阶用法 2. 模型序列化的作用?  
我第一次尝试进入 Django 原子事务。我想知道是否有可能像这样使用它: class TaskViewSet(MultiSerializerViewSet): @transaction.at
我有一个 drf 序列化程序,其中有一个我想重命名的字段: class UserBulkUploadSerializer(serializers.Serializer): ... is
我使用了 drf 并且还使用了 serializer 来检查用户输入。 这是我的serializer.py class BoardSerializer(serializers.Serializer):
我正在尝试序列化一个 CreateUserSerializer(ModelSerializer)我的代码如下。我的问题是它只会创建一个 User 而不是 UserProfile。 模型.py clas
我如何发布这个 JSON { "campaign": 27, "campaignName": "Prueba promo", "promotionType": 999, "items"
我正在构建一个 todo 应用程序,可以在 todo 上发布评论。 为此,我制作了一个可写的双嵌套序列化程序。它有效,但我编写的更新方法难以理解,因此我试图使其更具可读性。是否有更好的(或标准的)方法
有没有办法为特定的 View 类指定所需的自定义 header ?在我正在使用的 API 上,一些信息是使用 header 传递的,如果缺少 header ,我需要返回 BAD_REQUEST 或类似
我正在使用 DRF 并且我正在尝试创建一个对象,该对象具有多个外键以及需要在此过程中创建的相关对象。 这是我的模型的简化版本: class Race(models.Model): name =
我是一名优秀的程序员,十分优秀!