APIView和View的區別

<div id="cnblogs_post_body" class="blogpost-body cnblogs-markdown"> <h1 id="前言">前言</h1> <p>django中編輯視圖views.py有兩種方式,一種是基於類的實現,另一種是函數式的實現方式,兩種方法均可以用。<br> REST框架提供了一個APIView類,它是Django View類的子類。</p> <h1 id="view與apiview的區別">View與APIView的區別</h1> <p><code>View</code>是Django默認的視圖基類,<code>APIView</code>是REST framework提供的全部視圖的基類, 繼承自Django的<code>View</code>。</p> <p><code>APIView</code>與<code>View</code>的不一樣之處在於:</p> <ul> <li>傳入到視圖方法中的是REST framework的Request對象,而不是Django的HttpRequeset對象;</li> <li>視圖方法能夠返回REST framework的Response對象,視圖會爲響應數據設置(render)符合前端要求的格式;</li> <li>任何APIException異常都會被捕獲到,而且處理成合適的響應信息;APIException異常捕獲</li> <li>在進行dispatch()分發前,會對請求進行身份認證、權限檢查、流量控制。</li> </ul> <p>django的View部分源碼</p> <pre><code class="hljs python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">View</span>:</span> <span class="hljs-string">""" Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking. """</span>前端

http_method_names = [<span class="hljs-string">'get'</span>, <span class="hljs-string">'post'</span>, <span class="hljs-string">'put'</span>, <span class="hljs-string">'patch'</span>, <span class="hljs-string">'delete'</span>, <span class="hljs-string">'head'</span>, <span class="hljs-string">'options'</span>, <span class="hljs-string">'trace'</span>]

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self, **kwargs)</span>:</span>
    <span class="hljs-string">"""
    Constructor. Called in the URLconf; can contain helpful extra
    keyword arguments, and other things.
    """</span>
    <span class="hljs-comment"># Go through keyword arguments, and either save their values to our</span>
    <span class="hljs-comment"># instance, or raise an error.</span>
    <span class="hljs-keyword">for</span> key, value <span class="hljs-keyword">in</span> kwargs.items():
        setattr(self, key, value)</code></pre>

<p>REST framework的<code>APIView</code>繼承了django的<code>View</code>,部分源碼以下</p> <pre><code class="hljs delphi"><span class="hljs-keyword">class</span> APIView(View):python

# The following policies may be <span class="hljs-keyword">set</span> at either globally, <span class="hljs-keyword">or</span> 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

# Allow dependency injection <span class="hljs-keyword">of</span> other settings <span class="hljs-keyword">to</span> make testing easier.
settings = api_settings

schema = DefaultSchema()</code></pre>

<p><code>APIView</code>多了一些屬性和方法,好比:身份認證、權限檢查、流量控制</p> <ul> <li>authentication_classes 身份認證</li> <li>permission_classes 權限檢查</li> <li>throttle_classes 流量控制</li> </ul> <h1 id="django的view">django的View</h1> <p>先使用django自帶的view,獲取一個Card表裏面的卡號信息:<br> models.py設計card表</p> <pre><code class="hljs python"><span class="hljs-comment"># models.py</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Card</span><span class="hljs-params">(models.Model)</span>:</span> <span class="hljs-string">'''銀行卡 基本信息 # 做者:上海悠悠,QQ交流羣:750815713'''</span> card_id = models.CharField(max_length=<span class="hljs-number">30</span>, verbose_name=<span class="hljs-string">"卡號"</span>, default=<span class="hljs-string">""</span>) card_user = models.CharField(max_length=<span class="hljs-number">10</span>, verbose_name=<span class="hljs-string">"姓名"</span>, default=<span class="hljs-string">""</span>) add_time = models.DateField(auto_now=<span class="hljs-keyword">True</span>, verbose_name=<span class="hljs-string">"添加時間"</span>)django

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meta</span>:</span>
    verbose_name_plural = <span class="hljs-string">'銀行卡帳戶'</span>
    verbose_name = <span class="hljs-string">"銀行卡帳戶_基本信息"</span>
    
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
    <span class="hljs-keyword">return</span> self.card_id</code></pre>

<p>views.py視圖的編寫</p> <pre><code class="hljs python"><span class="hljs-keyword">from</span> django.http <span class="hljs-keyword">import</span> JsonResponse <span class="hljs-keyword">from</span> rest_framework <span class="hljs-keyword">import</span> serializers <span class="hljs-keyword">from</span> django.core <span class="hljs-keyword">import</span> serializers <span class="hljs-keyword">as</span> dj_serializers <span class="hljs-comment"># 避免和rest_framework裏面的serializers衝突</span> <span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> * <span class="hljs-keyword">from</span> django.views.generic.base <span class="hljs-keyword">import</span> View <span class="hljs-keyword">import</span> json <span class="hljs-comment"># 做者:上海悠悠,QQ交流羣:750815713</span>json

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CardListView</span><span class="hljs-params">(View)</span>:</span> <span class="hljs-string">'''基於django的view實現獲取card列表'''</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self, request)</span>:</span> data = {} cards = Card.objects.all() data[<span class="hljs-string">'result'</span>] = json.loads(dj_serializers.serialize(<span class="hljs-string">"json"</span>, cards)) <span class="hljs-keyword">return</span> JsonResponse(data)</code></pre>api

<p>urls.py設置訪問地址</p> <pre><code class="hljs python"><span class="hljs-keyword">from</span> apiapp <span class="hljs-keyword">import</span> views <span class="hljs-keyword">from</span> django.conf.urls <span class="hljs-keyword">import</span> url <span class="hljs-comment"># 做者:上海悠悠,QQ交流羣:750815713</span>markdown

urlpatterns = [ url(<span class="hljs-string">r'^api/v1/cards/$'</span>, views.CardListView.as_view()),app

]</code></pre>框架

<p>訪問<code>http://127.0.0.1:8000/api/v1/cards/</code>,測試結果</p> <p><img src="https://img2018.cnblogs.com/blog/1070438/201909/1070438-20190915151407005-1302501659.png"></p> <h1 id="rest-framework的apiview">REST framework的APIView</h1> <p>REST framework的<code>APIView</code>繼承了django的<code>View</code>類,先序列化Card類,這裏的序列化用<code>rest_framework</code>裏面的<code>ModelSerializer</code></p> <pre><code class="hljs python"><span class="hljs-keyword">from</span> rest_framework.response <span class="hljs-keyword">import</span> Response <span class="hljs-keyword">from</span> rest_framework.views <span class="hljs-keyword">import</span> APIView <span class="hljs-keyword">from</span> rest_framework <span class="hljs-keyword">import</span> serializers <span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> * <span class="hljs-keyword">from</span> rest_framework.permissions <span class="hljs-keyword">import</span> IsAuthenticated,AllowAny <span class="hljs-keyword">from</span> rest_framework.authentication <span class="hljs-keyword">import</span> TokenAuthentication <span class="hljs-comment"># 做者:上海悠悠,QQ交流羣:750815713</span>iview

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CardAPISerializer</span><span class="hljs-params">(serializers.ModelSerializer)</span>:</span> <span class="hljs-comment"># 繼承自ModelSerializer類</span> <span class="hljs-string">'''序列化數據的類,根據model表來獲取字段'''</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meta</span>:</span> model = Card fields = <span class="hljs-string">'all'</span>函數

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CardListAPIView</span><span class="hljs-params">(APIView)</span>:</span> <span class="hljs-string">'''REST framework的APIView實現獲取card列表 # 做者:上海悠悠,QQ交流羣:750815713'''</span> <span class="hljs-comment"># authentication_classes = (TokenAuthentication,) # token認證</span> <span class="hljs-comment"># permission_classes = (IsAuthenticated,) # IsAuthenticated 僅經過認證的用戶</span> permission_classes = (AllowAny,) <span class="hljs-comment"># 容許全部用戶</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get</span><span class="hljs-params">(self, request, format=None)</span>:</span>
    <span class="hljs-string">"""
    Return a list of all users.
    """</span>
    cards = Card.objects.all()
    serializer = CardAPISerializer(cards, many=<span class="hljs-keyword">True</span>)
    <span class="hljs-keyword">return</span> Response(serializer.data)</code></pre>

<p>配置urls.py,設置訪問地址</p> <pre><code class="hljs python"><span class="hljs-keyword">from</span> apiapp <span class="hljs-keyword">import</span> views <span class="hljs-keyword">from</span> django.conf.urls <span class="hljs-keyword">import</span> url <span class="hljs-comment"># 做者:上海悠悠,QQ交流羣:750815713</span>

urlpatterns = [ url(<span class="hljs-string">r'^api/v1/cardlist/$'</span>, views.CardListAPIView.as_view()),

]</code></pre>

<p>訪問<code>http://127.0.0.1:8000/api/v1/cardlist/</code>,測試結果</p> <p><img src="https://img2018.cnblogs.com/blog/1070438/201909/1070438-20190915154815694-63682914.png"></p>

</div>

相關文章
相關標籤/搜索