django序列化器嵌套
介绍 (Introduction)
The article introduces how to use DRF-Nested-Routers framework https://github.com/alanjds/drf-nested-routers to create URLs for nested resources. In this tutorial, our target is to create APIs for getting libraries and books.
本文介绍了如何使用DRF-Nested-Routers框架https://github.com/alanjds/drf-nested-routers来为嵌套资源创建URL。 在本教程中,我们的目标是创建用于获取库和书籍的API。
/api/libraries/ -> Get list of libraries
/api/libraries/{library_id}/books/ -> Get list of book in a library
/api/libraries/{library_id}/books/{book_id} -> Get details of a book
图表 (Diagram)
![Image for post](https://miro.medium.com/max/9999/1*OQF-OMC2gu-WttNkdNTKUg.png)
问题 (Problem)
Django Rest Framework supports to generate the URL by using Routers.
Django Rest Framework支持使用路由器生成URL。
REST framework adds support for automatic URL routing to Django, and provides you with a simple, quick and consistent way of wiring your view logic to a set of URLs.
REST框架增加了对自动URL路由到Django的支持,并为您提供了一种简单,快速且一致的方式将视图逻辑连接到一组URL。
Here’s an example of a simple URF conf using SimpleRouter according to Django Rest Framework document.
这是根据Django Rest Framework文档使用SimpleRouter的简单URF conf的示例。
from django.urls import path, include
from rest_framework import routers
from library import viewsrouter = routers.SimpleRouter()
router.register('libraries', views.LibraryViewSet)
router.register('books',views.BookViewSet)urlpatterns = [
path('', include(router.urls)),
]
By using the ViewSet, Django automatically generates these URLs under the hood:
通过使用ViewSet,Django会自动生成以下URL:
URL pattern:
^libraries/$
Name:'library-list'
URL模式:
^libraries/$
名称:'library-list'
URL pattern:
^librariess/{pk}/$
Name:'library-detail'
网址格式:
^librariess/{pk}/$
名称:'library-detail'
URL pattern:
^books/$
Name:'book-list'
网址格式:
^books/$
名称:'book-list'
URL pattern:
^books/{pk}/$
Name:'book-detail'
网址格式:
^books/{pk}/$
名称:'book-detail'
However, our target is to create the nested URL pattern ^librariess/{library_pk}/books/$
to get the list of books within a library and ^librariess/{library_pk}/books/{book_pk}/$
to get details of a book.
但是,我们的目标是创建嵌套的URL模式^librariess/{library_pk}/books/$
以获取库中的图书列表,并创建^librariess/{library_pk}/books/{book_pk}/$
以获取^librariess/{library_pk}/books/{book_pk}/$
详细信息书。
To do in Django, you have to explicitly define the URL pattern using a regular expression. In this case, the library_pk is an integer, so we can use \d+. If it is a string, you can use \w.
要在Django中进行操作,您必须使用正则表达式显式定义URL模式。 在这种情况下,library_pk是一个整数,因此我们可以使用\ d + 。 如果是字符串,则可以使用\ w。
# Get list of books in a library
url(r'^libraries/(?P<library_pk>\d+)/books/?$', views.BookViewSet.as_view({'get': 'list'}), name='library-book-list')# Get details of a book in a library
url(r'^libraries/(?P<library_pk>\d+)/books/(?P<pk>\d+)/?$', views.BookViewSet.as_view({'get': 'retrieve'}), name='library-book-detail')
Now you have to get the library_pk in the BookViewSet and get the books based on that ID
现在,您必须在BookViewSet中获取library_pk并根据该ID获取书籍
class BookViewSet(viewsets.ModelViewSet):
"""Viewset of book"""
queryset = Book.objects.all().select_related(
'library'
).prefetch_related(
'authors'
)
serializer_class = BookSerializer
def get_queryset(self, *args, **kwargs):
library_id = self.kwargs.get("library_pk")
try:
library = Library.objects.get(id=library_id)
except Library.DoesNotExist:
raise NotFound('A library with this id does not exist')
return self.queryset.filter(library=library)
Done. You can get access to the URL api/libraries/{library_pk}/books
and api/libraries/{library_pk}/books/{book_pk}/
in your browser now.
做完了 您现在可以在浏览器中访问URL api/libraries/{library_pk}/books
和api/libraries/{library_pk}/books/{book_pk}/
。
But imagine if your project scale-up and you have to implement many relational nested URLs, your code is likely not easy to read. There is an alternative way which is to use DRF-Nested-Routers framework.
但是想像一下,如果您的项目规模扩大了,并且必须实现许多关系嵌套的URL,那么您的代码可能不容易阅读。 还有一种替代方法是使用DRF嵌套路由器框架。
安装DRF嵌套路由器 (Install DRF-Nested-Routers)
You can install the library by using pip
您可以使用pip安装库
pip install drf-nested-routers
pip install drf-nested-routers
用法 (Usage)
By using DRF-Nested-Routers, the URL pattern will be simplified. It also increases the readability of the code.
通过使用DRF嵌套路由器,URL模式将得到简化。 这也增加了代码的可读性。
from rest_framework_nested import routersrouter = SimpleRouter()
router.register('libraries', views.LibraryViewSet)book_router = routers.NestedSimpleRouter(
router,
r'libraries',
lookup='library')book_router.register(
r'books',
views.BookViewSet,
basename='library-book'
)app_name = 'library'urlpatterns = [
path('', include(router.urls)),
path('', include(book_router.urls)),
]
结论 (Conclusion)
Again it depends on the requirement of your API to make a decision whether or not to use the DRF-Nested-Routers. The regular expression pattern itself is not very too hard to understand, so you can use it if you don’t have many nested relational URLs.
再次取决于您的API需求,以决定是否使用DRF-Nested-Router。 正则表达式模式本身并不是很难理解,因此如果您没有很多嵌套的关系URL,则可以使用它。
Happy coding. If you have any queries, feel free to contact me. I am happy to discuss and connect with you.
快乐的编码。 如有任何疑问,请随时与我联系。 很高兴与您讨论并建立联系。
Twitter: https://twitter.com/steve_pham93
推特: https : //twitter.com/steve_pham93
Email: duythuc28493@gmail.com
电子邮件:duythuc28493@gmail.com
下载完整的项目 (Download the full project)
https://github.com/stevethucpham/demo-django-drf-nested-router
https://github.com/stevethucpham/demo-django-drf-nested-router
django序列化器嵌套