欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

DjangoREST_framework框架01

restframework是基于restful協(xié)議開發(fā)的Django框架擴(kuò)展

創(chuàng)新互聯(lián)建站是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷策劃、微信平臺小程序開發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立10年以來,已經(jīng)為成百上千家成都圍欄護(hù)欄各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)。現(xiàn)在,服務(wù)的成百上千家客戶與我們一路同行,見證我們的成長;未來,我們一起分享成功的喜悅。

restful協(xié)議

要理解RESTful架構(gòu),最好的方法就是去理解Representational State Transfer這個(gè)詞組到底是什么意思,翻譯是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

資源(Resources)

一切皆是資源,所謂"資源",就是網(wǎng)絡(luò)上的一個(gè)實(shí)體,或者說是網(wǎng)絡(luò)上的一個(gè)具體信息,每種資源對應(yīng)一個(gè)特定的URI。要獲取這個(gè)資源,訪問它的URI就可以。

表現(xiàn)層(Representation)

"資源"是一種信息實(shí)體,它可以有多種外在表現(xiàn)形式。我們把"資源"具體呈現(xiàn)出來的形式,叫做它的"表現(xiàn)層"(Representation)

狀態(tài)轉(zhuǎn)化(State Transfer)

訪問一個(gè)網(wǎng)站,就代表了客戶端和服務(wù)器的一個(gè)互動過程,客戶端用到的手段,只能是HTTP協(xié)議。具體來說,就是HTTP協(xié)議里面,四個(gè)表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應(yīng)四種基本操作:GET用來獲取資源,POST用來新建資源(也可以用于更新資源),PUT用來更新資源,DELETE用來刪除資源。

綜合上面的解釋,我們總結(jié)一下什么是RESTful架構(gòu):

每一個(gè)URI代表一種資源;
客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;
客戶端通過四個(gè)HTTP動詞,對服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

HTTP動詞

常用的HTTP動詞有下面五個(gè)(括號里是對應(yīng)的SQL命令)

GET(SELECT):從服務(wù)器取出資源(一項(xiàng)或多項(xiàng))。
POST(CREATE):在服務(wù)器新建一個(gè)資源。
PUT(UPDATE):在服務(wù)器更新資源(客戶端提供改變后的完整資源)。
PATCH(UPDATE):在服務(wù)器更新資源(客戶端提供改變的屬性)。
DELETE(DELETE):從服務(wù)器刪除資源。

過濾信息(Filtering)

下面是一些常見的參數(shù)

?limit=10:指定返回記錄的數(shù)量
?offset=10:指定返回記錄的開始位置。
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數(shù)。
?sortby=name&order=asc:指定返回結(jié)果按照哪個(gè)屬性排序,以及排序順序。
?animal_type_id=1:指定篩選條件

返回結(jié)果

針對不同操作,服務(wù)器向用戶返回的結(jié)果應(yīng)該符合以下規(guī)范

GET /collection:返回資源對象的列表(數(shù)組)
GET /collection/resource:返回單個(gè)資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個(gè)空文檔

以book表增刪改查來舉例

舊來的方式,在url中有動詞

請求方式url對應(yīng)視圖備注
GET /books/ books 返回當(dāng)前所有數(shù)據(jù)
POST /books/add/ addbook 提交數(shù)據(jù)
POST /books/(\d+)/change/ changebook 更新數(shù)據(jù)
GET /books/(\d+)/delete/ delbook 刪除數(shù)據(jù)

新的方式

請求方式url對應(yīng)視圖備注
GET /books/ books 返回當(dāng)前所有數(shù)據(jù)
POST /books/ books 提交數(shù)據(jù)
GET /books/(\d+) bookdetail 當(dāng)前查看的單條數(shù)據(jù)
PUT /books/(\d+) bookdetail 更新數(shù)據(jù)
DELTET /books/(\d+) bookdetail 刪除數(shù)據(jù)

對應(yīng)視圖

class Books(View):
    def get(self,request):
        pass  # 查看所有書籍

    def post(self,request):
        pass  # 添加書籍

class BooksDetail(View):
    def get(self,request,id):
        pass  # 查看具體書籍

    def put(self,request,id):
        pass  # 更新某本書籍

    def delete(self,request,id):
        pass  # 刪除某本書籍

參考資料:https://www.cnblogs.com/yuanchenqi/articles/8719520.html

序列化組件初探

序列化方式1 model_to_dict

model_to_dict是Django ORM下的語句,可以把model對象轉(zhuǎn)換成一個(gè)字典

from django.forms.models import model_to_dict
from app01.models import Publish
obj = Publish.objects.filter(pk=1).first()
obj
<Publish: 蘋果出版社>
model_to_dict(obj)
{'id': 1, 'name': '蘋果出版社', 'email': '123@qq.com'}

序列化方式2

#QuerySet無法直接序列化,需要轉(zhuǎn)換成list
publish_list = list(Publish.objects.all().values("name", "email"))
print(publish_list)

[{'name': '蘋果出版社', 'email': '123@qq.com'}, {'name': '橘子出版社', 'email': '345@qq.com'}]

序列化方式3

publish_list = Publish.objects.filter(pk=1)

#這是Django原生的serializers
from django.core import serializers
#serialize(format, queryset, **options)
ret = serializers.serialize("json", publish_list)

print(ret)
[{"model": "app01.publish", 
  "pk": 1, 
  "fields": {
              "name": "\u82f9\u679c\u51fa\u7248\u793e", 
              "email": "123@qq.com"
            }
 }
]

上面的三種方式都沒有用到restframework

序列化方式4

這里利用restframework封裝出來的serializers,其用法與Django的Form組件很相似
可以序列化QuerySet和model對象

from rest_framework.views import APIView
from rest_framework import serializers

#創(chuàng)建一個(gè)序列化類
class PublishSerializers(serializers.Serializer):
    name = serializers.CharField()
    email = serializers.CharField()

class PublishView(APIView):

    def get(self, request):

        publish_list = Publish.objects.filter(pk=1)

        ret = PublishSerializers(publish_list, many=True)
        #可以序列化QuerySet和model對象,many=True代表轉(zhuǎn)換的是QuerySet,默認(rèn)為False
        print(ret.data)

        #結(jié)果
        #[OrderedDict([('name', '蘋果出版社'), ('email', '123@qq.com')])]
        #得出一個(gè)OrderedDict對象,這個(gè)對象本質(zhì)就是有序字典
        return HttpResponse("ok")

    def post(self, request):
        pass

原生request與restframework的request

原生request

使用postman發(fā)送x-www-form-urlencoded數(shù)據(jù)后看一下request.body和request.POST都收到了什么

def post(self, request):

    print("POST==>", request.POST)
    print("body==>", request.body)

    return HttpResponse("POST ok")

結(jié)果:

POST==> <QueryDict: {'a': ['1'], 'b': ['2']}> #處理過的數(shù)據(jù)
body==> b'a=1&b=2' #請求體中的數(shù)據(jù),沒有處理過的原始數(shù)據(jù)

由上可知,request.POST拿到一個(gè)字典,其過程就是判斷contentType如果等于urlencoded,那么就將接收到的數(shù)據(jù)轉(zhuǎn)換為一個(gè)字典,如果是其它類型例如JSON那么request.POST就是個(gè)空字典
也就是說原生Django的request只支持form表單數(shù)據(jù)的解析
如果傳過來的是JSON數(shù)據(jù),那么就只能從request.body中拿到字符串,然后再反序列化成字典

request.POST:
    if contentType:urlencoded:
        a=1&b=2----->{"a":1,"b":2}

restframework的request

APIViwe還是繼承原生Django的View,但自己構(gòu)建了一個(gè)dispatch(restframework的關(guān)鍵點(diǎn)都在這里,可以看前面的博客了解CBV)
在這個(gè)dispatch中構(gòu)建了一個(gè)新的request

class PublishView(APIView):

    def post(self, request):

    #新的request支持的操作
    print("request.data==>", request.data)
    print("request.data_type==>", type(request.data))

    #前端發(fā)送JSON數(shù)據(jù),接收到的是一個(gè)字典,說明接收的同時(shí)完成了反序列化
    #request.data==> {'a': 1, 'b': 2}
    #request.data_type==> <class 'dict'>

    return HttpResponse("POST ok")

如果前端POST請求發(fā)送過來一個(gè)form表單,或者是GET請求,則會構(gòu)建成QueryDict

總結(jié)一下:
request.data 接收到的是Body中的數(shù)據(jù)

GET請求可以用request.GET來取

序列化字段

開發(fā)我們的Web API的第一件事是為我們的Web API提供一種將代碼片段實(shí)例序列化和反序列化為諸如json之類的表示形式的方式。我們可以通過聲明與Django forms非常相似的序列化器(serializers)來實(shí)現(xiàn)。

序列化類的使用

models

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.IntegerField()
    pub_date = models.DateField()
    publish = models.ForeignKey("Publish")
    authors = models.ManyToManyField("Author")

    def __str__(self):
        return self.title

class Publish(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    def __str__(self):
        return self.name

views

from rest_framework.views import APIView
from .models import *
from rest_framework import serializers
from rest_framework.response import Response

#創(chuàng)建一個(gè)序列化類
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    pub_date = serializers.DateField()

    #下面兩個(gè)是一對多和多對多的字段

    #source="publish.name"可以理解為取obj.publish.name
    publish = serializers.CharField(source="publish.name")

    #SerializerMethodField為多對多服務(wù),與get_authors配合(類似鉤子)使用
    #可以理解為get_authors(obj),此時(shí)authors的返回值取決于get_authors的返回結(jié)果
    authors = serializers.SerializerMethodField()

    def get_authors(self, obj):
        temp = []
        for obj in obj.authors.all():
            temp.append(obj.name)
        return temp

class BookView(APIView):

    def get(self, request):
        book_list = Book.objects.all()

        ret = BookSerializers(book_list, many=True)

        #此處的Response來自rest_framework
        return Response(ret.data)

序列化BookSerializers(book_list, many=True)的過程可以簡單理解為下面的例子:

temp = []
for obj in book_list:
    temp.append({
        "title":obj.title,
        "price":obj.price,
        "pub_date":obj.pub_date,
        "publist":obj.publish.name
        "authors":get_authors(obj)
    })

restframework的Response

在上面的例子中Response把結(jié)果從有序字典轉(zhuǎn)換為JSON格式了,其結(jié)果為:

[
    {
        "title": "三體",
        "price": 18,
        "pub_date": null,
        "publish": "蘋果出版社",
        "authors": [
            "alex",
            "egon"
        ]
    },
    {
        "title": "go",
        "price": 58,
        "pub_date": null,
        "publish": "橘子出版社",
        "authors": [
            "egon"
        ]
    }
]

ModelSerializer

定義一個(gè)ModelSerializer序列化器

GET請求
類似于ModleForm,將Modle直接序列化

class BookModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"
        #fields = ["id", "title", "pub_time"]
        #exclude = ["user"]
        #分別是所有字段 包含某些字段 排除某些字段
        #depth = 1
        #depth 代表找嵌套關(guān)系的第幾層
        #注意:當(dāng)序列化類MATE中定義了depth時(shí),這個(gè)序列化類中引用字段(外鍵)則自動變?yōu)橹蛔x

    #自定義字段  
    #下面兩個(gè)一對多和多對多的字段

    #source="publish.name"可以理解為取obj.publish.name
    publish = serializers.CharField(source="publish.name")

    #SerializerMethodField為多對多服務(wù)
    #與get_authors配合(類似鉤子),可以理解為get_authors(obj),此時(shí)authors的返回值取決于get_authors的返回結(jié)果
    authors = serializers.SerializerMethodField()

    def get_authors(self, obj):
        temp = []
        for obj in obj.authors.all():
            temp.append(obj.name)
        return temp

結(jié)果:

[
    {
        "id": 1,
        "publish": "蘋果出版社",
        "authors": [
            "alex",
            "egon"
        ],
        "title": "三體",
        "price": 18,
        "pub_date": null
    },
    {
        "id": 2,
        "publish": "橘子出版社",
        "authors": [
            "egon"
        ],
        "title": "go",
        "price": 58,
        "pub_date": null
    }
]

提交post請求,反序列化

class BookModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"

class BookView(APIView):
    def post(self, request):

        #request.data中是post請求的數(shù)據(jù)
        bs = BookModelSerializers(data=request.data, many=False)

        if bs.is_valid():
            #打印正確數(shù)據(jù)
            print(bs.validated_data)
            bs.save() #create方法
            #返回當(dāng)前添加的內(nèi)容
            return Response(bs.data)

        else:
            print(bs.errors)
            #返回錯(cuò)誤項(xiàng)目信息
            return Response(bs.errors)

在Postman中提交JSON數(shù)據(jù)

{"title": "Python", "price":100, "pub_date": "2012-12-12", "publish":1,  "authors":[1,2]}

重寫save中的create方法

Serializer提供了.is_valid()和.save()方法
如果是post請求那么.save()就是調(diào)用create方法,如果是put請求,那么.save()就是調(diào)用update方法
上面我們自定義了publish的返回?cái)?shù)據(jù),因此我們要自己寫一個(gè)create方法

#向http://127.0.0.1:8000/books/發(fā)送post請求
{
    "title": "go第三版",
    "price": 70,
    "pub_date": "2017-10-01",
    "publish": 1,
    "authors": [
        1,
        2
    ]
}

views.py

class BookModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"

    publish = serializers.CharField(source="publish.name")

    #validated_data是所有接受到的數(shù)據(jù),此時(shí)已經(jīng)反序列化為字典
    def create(self, validated_data):

        #print("validated_data==>", validated_data)
        #查看發(fā)現(xiàn){'publish': {'name': '1'},這個(gè)name就是上面自定義返回內(nèi)容是改變的key值
        #{'publish': {'name': '1'}, 'title': 'go第三版', 'price': 70, 'pub_date': datetime.date(2017, 10, 1), 'authors': [<Author: alex>, <Author: egon>]}

        obj = Book.objects.create(title=validated_data["title"],
                                   price=validated_data["price"],
                                   pub_date=validated_data["pub_date"],
                                   publish_id=validated_data["publish"]["name"])

        obj.authors.add(*validated_data["authors"])

        return obj

class BookView(APIView):

    def post(self, request):

        #request.data中是post請求的數(shù)據(jù)
        bs = BookModelSerializers(data=request.data)

        if bs.is_valid():
            bs.save() #create方法
            #返回當(dāng)前添加的內(nèi)容
            return Response(bs.data)

        else:
            #返回錯(cuò)誤項(xiàng)目信息
            return Response(bs.errors)

單條數(shù)據(jù)的get和put請求

class BookDetailView(APIView):

    def get(self, request, id):
        book = Book.objects.filter(pk=id).first()

        bs = BookModelSerializers(book, context={'request': request})

        return Response(bs.data)

    def put(self, request, id):
        book = Book.objects.filter(pk=id).first()

        bs = BookModelSerializers(book, data=request.data)

        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:
            return Response(bs.errors)

超鏈接API:Hyperlinked

class BookModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"

    publish = serializers.HyperlinkedIdentityField(
        view_name="detail_publish",  #url中反向解析的別名
        lookup_field="publish_id",   #對應(yīng)的字段名稱
        lookup_url_kwarg="pk",       #url中有名分組的名稱
    )

urls部分:
使用有名分組和反向解析

from app01 import views
urlpatterns = [
    ......
    url(r'^publish/(?P<pk>\d+)/$', views.PublishDetailView.as_view(), name="detail_publish"),
]

views部分:
注意有名分組中的別名要與視圖中的名稱對應(yīng)

class PublishDetailView(APIView):

    def get(self, request, pk): #這個(gè)pk與url中的有名分組pk對應(yīng)
        publish = Publish.objects.filter(pk=pk).first()

        bs = PublishModelSerializers(publish)

        return Response(bs.data)

class BookDetailView(APIView):

    def get(self, request, id):
        book = Book.objects.filter(pk=id).first()

        #注意添加context={'request': request}
        bs = BookModelSerializers(book, context={'request': request})

        return Response(bs.data)

訪問
向http://127.0.0.1:8000/books/1發(fā)送GET請求
返回結(jié)果:

{
    "id": 1,
    "publish": "http://127.0.0.1:8000/publish/1/",
    "title": "三體",
    "price": 18,
    "pub_date": null,
    "authors": [
        1,
        2
    ]
}

分享文章:DjangoREST_framework框架01
網(wǎng)站網(wǎng)址:http://chinadenli.net/article20/iigejo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站網(wǎng)站維護(hù)動態(tài)網(wǎng)站用戶體驗(yàn)虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化