欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django REST為文件屬性輸出完整URL的方法

 更新時(shí)間:2017年12月18日 09:47:32   作者:TUALATRIX  
這篇文章主要給大家介紹了關(guān)于Django REST如何為文件屬性輸出完整URL的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用django具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。

前言

我的 App 項(xiàng)目的 API 部分是使用 Django REST Framework 來(lái)搭建的,它可以像搭積木一樣非常方便地搭出 API,兼具方便和靈活。

django是一個(gè)神奇的框架,而restframework又是遵循了這個(gè)框架的另一個(gè)神奇的框架,然而由于restframework的文檔稀爛無(wú)比,很多時(shí)候你必須看源碼才能寫出科學(xué)的代碼,這擋住了很多新手的路。

在使用的過(guò)程中我也積累了一些小技巧,這里寫一則關(guān)于如何為文件屬性輸出完整 URL 的字段。

實(shí)現(xiàn)方法

一個(gè)典型的案例是,當(dāng)請(qǐng)求 /profile/ 這個(gè) API 的時(shí)候,返回類似于這樣的結(jié)果:

{
 "id": 1,
 "nickname": "管理員",
 "mobilephone": "1234567890",
 "avatar": "/media/profiles/2017/12/17/avatar.png"
}

在 Django REST 的定義中,我使用了自定義的一個(gè)擴(kuò)展自 rest_framework.views.APIView 的 ProfileView 類型,實(shí)現(xiàn)了它的 get 方法,來(lái)給認(rèn)證的用戶返回一個(gè) Profile 對(duì)象:

class ProfileView(APIView):
 def get(self, request):
  user = request.user
  if user.is_authenticated:
   profile = Profile.objects.get(user=user)
   return Response(ProfileSerializer(profile).data)
  else:
   raise exceptions.AuthenticationFailed('Not authenticated user!')

這里的邏輯很簡(jiǎn)單,判斷請(qǐng)求當(dāng)前 API 的用戶是不是已經(jīng)驗(yàn)證過(guò)的用戶,如果是的話,再得到它的 Profile,再通過(guò) ProfileSerializer 把 profile 實(shí)例序列化成 JSON 對(duì)象。如果不是已驗(yàn)證用戶,則會(huì)返回 401 驗(yàn)證失敗相關(guān)信息。

以上輸出的內(nèi)容,交給 Web 前端使用是沒什么問題的,但如果是給 App 使用,那么 avatar 這個(gè)文件屬性的相對(duì) URL 不太合適,于是我們要改造一下這個(gè) API,使其能輸出絕對(duì) URL。

如何做呢?只需要將上面的 get 方法,稍加修改即可:

-class ProfileView(APIView):
+class ProfileView(generics.GenericAPIView):
  parser_classes = (MultiPartParser, FormParser)
+ serializer_class = ProfileSerializer
  def get(self, request):
   user = request.user
   if user.is_authenticated:
    profile = Profile.objects.get(user=user)
-   return Response(ProfileSerializer(profile).data)
+   serializer = self.get_serializer(profile)
+   return Response(serializer.data)
   else:
    raise exceptions.AuthenticationFailed('Not authenticated user!')

不同于之前繼承自 APIView,現(xiàn)在繼承自 generics.GenericAPIView,這是一個(gè)更通用的類,可以看到,這里通過(guò)手動(dòng)構(gòu)建 ProfileSerializer 改成通過(guò) self.get_serializer 來(lái)進(jìn)行,這里有什么不同呢?

還得看看 Django REST 的源碼,GenericAPIView 這個(gè)類的 get_serializer 在做什么。

def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)

可以看到,這個(gè)方法在創(chuàng)建 serializer 的時(shí)候,會(huì)把 context 傳進(jìn)去,而 get_serializer_context 也是一個(gè)固定方法,它會(huì)把 request、view 和 format 這些信息包含在里面。

那么 request、view 和 format 這些信息,是如何用在 serializer 里面,最后把一個(gè)文件對(duì)象的全路徑展開的呢?

省略中間 serializer 一系列序列化過(guò)程,當(dāng)它遇到 FileField 的時(shí)候,會(huì)通過(guò)判斷 context 里面有沒有 reuqest,有的話,就調(diào)用 request.build_absolute_uri(url) 方法,把絕對(duì)地址 build 出來(lái),而不是默認(rèn)存在數(shù)據(jù)庫(kù)里的相對(duì)地址。

def to_representation(self, value):
  if not value:
   return None
  use_url = getattr(self, 'use_url', api_settings.UPLOADED_FILES_USE_URL)
  if use_url:
   if not getattr(value, 'url', None):
    # If the file has not been saved it may not have a URL.
    return None
   url = value.url
   request = self.context.get('request', None)
   if request is not None:
    return request.build_absolute_uri(url)
   return url
  return value.name

這就是為什么通過(guò) GenericAPIView 來(lái)輸出 API 對(duì)象,文件屬性默認(rèn)有絕對(duì)路徑而不是相對(duì)路徑的原因了~

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 超實(shí)用Python庫(kù)之lxml使用方法詳解

    超實(shí)用Python庫(kù)之lxml使用方法詳解

    lxml是python的一個(gè)解析庫(kù),支持HTML和XML的解析,支持XPath解析方式,下面這篇文章主要給大家介紹了關(guān)于超實(shí)用Python庫(kù)之lxml使用方法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • python讀取Kafka實(shí)例

    python讀取Kafka實(shí)例

    今天小編就為大家分享一篇python讀取Kafka實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • Python機(jī)器學(xué)習(xí)NLP自然語(yǔ)言處理基本操作電影影評(píng)分析

    Python機(jī)器學(xué)習(xí)NLP自然語(yǔ)言處理基本操作電影影評(píng)分析

    本文是Python機(jī)器學(xué)習(xí)NLP自然語(yǔ)言處理系列文章,帶大家開啟一段學(xué)習(xí)自然語(yǔ)言處理 (NLP) 的旅程。本篇文章主要學(xué)習(xí)NLP自然語(yǔ)言處理基本操電影影評(píng)分析
    2021-09-09
  • Python中文文本處理利器jieba分詞庫(kù)使用

    Python中文文本處理利器jieba分詞庫(kù)使用

    這篇文章主要給大家介紹了關(guān)于Python中文文本處理利器jieba分詞庫(kù)使用的相關(guān)資料,jieba是python中一個(gè)重要的第三方中文分詞函數(shù)庫(kù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • python基礎(chǔ)教程之基本數(shù)據(jù)類型和變量聲明介紹

    python基礎(chǔ)教程之基本數(shù)據(jù)類型和變量聲明介紹

    這篇文章主要介紹了python基礎(chǔ)教程之基本數(shù)據(jù)類型和變量聲明介紹,首先講解了變量聲明的一些知識(shí),然后列出最常用的基本數(shù)據(jù)類型,需要的朋友可以參考下
    2014-08-08
  • python中的sys模塊和os模塊

    python中的sys模塊和os模塊

    這篇文章主要介紹了python中的sys模塊和os模塊,sys模塊提供對(duì)解釋器使用或維護(hù)的一些變量的訪問,以及與解釋器強(qiáng)烈交互的函數(shù),os模塊提供了多數(shù)操作系統(tǒng)的功能接口函數(shù),下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-03-03
  • Python讀取sqlite數(shù)據(jù)庫(kù)文件的方法分析

    Python讀取sqlite數(shù)據(jù)庫(kù)文件的方法分析

    這篇文章主要介紹了Python讀取sqlite數(shù)據(jù)庫(kù)文件的方法,結(jié)合實(shí)例形式分析了Python引入sqlite3模塊操作sqlite數(shù)據(jù)庫(kù)的讀取、SQL命令執(zhí)行等相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • Django 路由層URLconf的實(shí)現(xiàn)

    Django 路由層URLconf的實(shí)現(xiàn)

    這篇文章主要介紹了Django 路由層URLconf的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • python生成每日?qǐng)?bào)表數(shù)據(jù)(Excel)并郵件發(fā)送的實(shí)例

    python生成每日?qǐng)?bào)表數(shù)據(jù)(Excel)并郵件發(fā)送的實(shí)例

    今天小編就為大家分享一篇python生成每日?qǐng)?bào)表數(shù)據(jù)(Excel)并郵件發(fā)送的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • Python中flatten( )函數(shù)及函數(shù)用法詳解

    Python中flatten( )函數(shù)及函數(shù)用法詳解

    flatten是numpy.ndarray.flatten的一個(gè)函數(shù),即返回一個(gè)一維數(shù)組。這篇文章主要介紹了Python中flatten( )函數(shù),需要的朋友可以參考下
    2018-11-11

最新評(píng)論