溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Rest Framework:三、HyperlinkedidentityField用法

發(fā)布時(shí)間:2020-07-14 13:01:23 來源:網(wǎng)絡(luò) 閱讀:1364 作者:a120518129 欄目:編程語言

 一、HyperlinkedIdentityField(用的很少)

環(huán)境配置:

1、使django支持mysql(不再介紹)

2、settings.py文件INSTALLED_APPS字段中添加"rest_framework"

urls.py

url(r'^books/', views.Books.as_view()),
url(r'^publish/(?P<pk>\d+)', views.Publish.as_view(),name='ttt'),

app01/server.py

from rest_framework import serializers

class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

class BookSerializer(serializers.Serializer):
    name = serializers.CharField()
    # publish = serializers.CharField()
    # 把名字換成鏈接地址,# view_name:路由的別名 # lookup_field:根據(jù)表指定字段,來拼路徑,生成鏈接 # lookup_url_kwarg:默認(rèn)是pk,(urls.py中的 publish/(?P<pk>\d+),指定的pk)可以不寫,反向解析有名分組的名字。
    publish = serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pk')

views.py

from django.shortcuts import HttpResponse,render
from rest_framework.views import APIView
from django.http import JsonResponse
from app01 import models
from app01.server import BookSerializer
# Create your views here.
class Books(APIView):
    def get(self,request,*args,**kwargs):
        ret=models.Book.objects.all()
        book_ser=BookSerializer(ret,many=True,context={'request':request})
        print(book_ser.data)
        return JsonResponse(book_ser.data,safe=False)
class Publish(APIView):
    def get(self,request,*args,**kwargs):
        return HttpResponse('ok')

models.py

from django.db import models
# Create your models here.
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    # 外鍵對應(yīng)數(shù)據(jù)庫表中的字段名后面會自動加"_id"        # on_delete=models.CASCADE 級聯(lián)刪除
    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    # ManyToManyField 自動創(chuàng)建第三張表,本表名_到你對應(yīng)多的表名名字,自動幫你把表名轉(zhuǎn)小寫
    authors = models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name
class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)

class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()
    def __str__(self):
        return self.name
    def test(self):
        return self.email

最后使用:

python3 manage makemigrations
python3 manage migrate

數(shù)據(jù)庫的表中添加數(shù)據(jù):

Rest Framework:三、HyperlinkedidentityField用法Rest Framework:三、HyperlinkedidentityField用法

使用postman驗(yàn)證:

Rest Framework:三、HyperlinkedidentityField用法

總結(jié):

-1 publish = serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pky')

-2 view_name:路由的別名,lookup_field:根據(jù)表的哪個(gè)字段,來拼路徑,lookup_url_kwarg:反向解析有名分組的名字

-3 寫路由:url(r'^publish/(?P<pky>\d+)', views.Publish.as_view(),name='ttt'),

-4 實(shí)例化序列化類的時(shí)候,需要把request對象傳過去

book_ser=BookSerializer(ret,many=True,context={'request': request})

二、序列化組件的反序列化和保存

環(huán)境配置:

1、使django支持mysql(不再介紹)

2、settings.py文件INSTALLED_APPS字段中添加"rest_framework"

urls.py

url(r'^books/', views.Books.as_view()),
url(r'^publish/(?P<pk>\d+)', views.Publish.as_view(), name='ttt'),

models.py

from django.db import models


# Create your models here.

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    # 外鍵對應(yīng)數(shù)據(jù)庫表中的字段名后面會自動加"_id"        # on_delete=models.CASCADE 級聯(lián)刪除
    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    # ManyToManyField 自動創(chuàng)建第三張表,本表名_到你對應(yīng)多的表名名字,自動幫你把表名轉(zhuǎn)小寫
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

    def test(self):
        return self.email

app01/server.py

from rest_framework import serializers
from app01 import models

class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
    authors = serializers.CharField(required=False)

views.py

from django.shortcuts import HttpResponse, render
from rest_framework.views import APIView
from django.http import JsonResponse
from app01 import models
from app01.server import BookSerializer


# Create your views here.
class Books(APIView):
    def get(self, request, *args, **kwargs):
        ret = models.Book.objects.all()
        book_ser = BookSerializer(ret, many=True, context={'request': request})
        print(book_ser.data)
        return JsonResponse(book_ser.data, safe=False)

    def post(self, request, *args, **kwargs):
        # 前端傳過來的數(shù)據(jù)從data中取
        # 用序列化類的數(shù)據(jù)校驗(yàn)
        # data參數(shù),是要校驗(yàn)的數(shù)據(jù)
        response = {'status': 100, 'msg': '成功'}
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            # 如果數(shù)據(jù)校驗(yàn)通過,is_valid是True
            # 保存到數(shù)據(jù)庫,ser是誰的對象?繼承了ModelSerializer的類的對象
            ser.save()
        else:
            response['status'] = 101
            response['msg'] = ser.errors
        return JsonResponse(response, safe=False)


class Publish(APIView):
    def get(self, request, *args, **kwargs):
        return HttpResponse('ok')

使用postman提交數(shù)據(jù)驗(yàn)證:


{

"name":"水滸傳",

"price":"23.00",

"publish_date":"2018-12-01",

"publish":1

}Rest Framework:三、HyperlinkedidentityField用法


app01/server.py

# 其他一樣,只是加了這一段,驗(yàn)證

 # name = serializers.CharField(min_length=3, error_messages={'required': '該字段必填','min_length':'最短3位'})

from rest_framework import serializers
from app01 import models


class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

    name = serializers.CharField(min_length=3, error_messages={'required': '該字段必填','min_length':'最短3位'})
    authors = serializers.CharField(required=False)

# 使用postman post提交數(shù)據(jù)驗(yàn)證

Rest Framework:三、HyperlinkedidentityField用法


三、序列化組件修改功能

環(huán)境與上面一樣

urls.py

url(r'^books/$', views.Books.as_view()),
url(r'^books/(?P<pk>\d+)', views.BooksDetail.as_view()),

app01/server.py

from rest_framework import serializers
from app01 import models

class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

    name = serializers.CharField(min_length=3, error_messages={'required': '該字段必填','min_length':'最短3位'})
    authors = serializers.CharField(required=False)

views.py

from django.shortcuts import HttpResponse, render
from rest_framework.views import APIView
from django.http import JsonResponse
from app01 import models
from app01.server import BookSerializer


# Create your views here.
class BooksDetail(APIView):
    def get(self, request,pk):
        response = {'status': 100, 'msg': '成功'}
        ret = models.Book.objects.all().filter(pk=pk).first()
        if ret:
            # 序列化單條,many=False
            book_ser = BookSerializer(ret, many=False)
            print(book_ser.data)
            response['data']=book_ser.data
        else:
            response['status']=101
            response['msg']='查詢不存在'
        return JsonResponse(response, safe=False)

    def put(self,request,pk):
        response = {'status': 100, 'msg': '成功'}
        ret = models.Book.objects.all().filter(pk=pk).first()
        if ret:
            # 數(shù)據(jù)校驗(yàn)
            # 傳instance和不傳instance,傳instance的區(qū)別
            # 不傳instance,調(diào)save(),往數(shù)據(jù)庫新增數(shù)據(jù)
            # 傳instance,調(diào)save(),修改數(shù)據(jù)
            ser=BookSerializer(data=request.data,instance=ret)
            if ser.is_valid():
                ser.save()
            else:
                response['status']=101
                response['msg']=ser.errors
        else:
            response['status']=102
            response['msg']='修改的對象不存在'
        return JsonResponse(response,safe=False)

class Books(APIView):
    def get(self, request, *args, **kwargs):
        ret = models.Book.objects.all()
        book_ser = BookSerializer(ret, many=True, context={'request': request})
        print(book_ser.data)
        return JsonResponse(book_ser.data, safe=False)

    def post(self, request, *args, **kwargs):
        # 前端傳過來的數(shù)據(jù)從data中取
        # 用序列化類的數(shù)據(jù)校驗(yàn)
        # data參數(shù),是要校驗(yàn)的數(shù)據(jù)
        response = {'status': 100, 'msg': '成功'}
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            # 如果數(shù)據(jù)校驗(yàn)通過,is_valid是True
            # 保存到數(shù)據(jù)庫,ser是誰的對象?繼承了ModelSerializer的類的對象
            ser.save()
        else:
            response['status'] = 101
            response['msg'] = ser.errors
        return JsonResponse(response, safe=False)

class Publish(APIView):
    def get(self, request, *args, **kwargs):
        return HttpResponse('ok')

models.py不變

python3 manage makemigrations
python3 manage migrate

使用postman 的put請求方式修改數(shù)據(jù)

Rest Framework:三、HyperlinkedidentityField用法

數(shù)據(jù)庫查看數(shù)據(jù)

Rest Framework:三、HyperlinkedidentityField用法

總結(jié):

   -序列化組件的數(shù)據(jù)校驗(yàn)

   -類比forms組件

   -字段是否必填,通過required,來控制 authors=serializers.CharField(required=False)

   -數(shù)據(jù)校驗(yàn),生成一個(gè)序列化類的對象

   -對象.is_valid()

   -新增數(shù)據(jù):

   -對象.save()

   -修改數(shù)據(jù):

   -在生成對象的時(shí)候,需要傳instanse=查詢出來的對象

   -對象.save()

四、序列化組件數(shù)據(jù)校驗(yàn)功能的鉤子函數(shù)

    -局部

    -全局

環(huán)境與以上配置一樣,只有這個(gè)文件不一樣。

局部鉤子:

app01/server.py

from rest_framework import serializers
from app01 import models
from rest_framework.exceptions import ValidationError

class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

    name = serializers.CharField(min_length=3, error_messages={'required': '該字段必填','min_length':'最短3位'})
    authors = serializers.CharField(required=False)

    # 局部鉤子
    def validate_name(self,value):
        print(value)
        if value.startswith('sb'):
            raise ValidationError('不能以sb開頭')
        else:
            return value

使用postman 驗(yàn)證

Rest Framework:三、HyperlinkedidentityField用法

全局鉤子:

app01/server.py

from rest_framework import serializers
from app01 import models
from rest_framework.exceptions import ValidationError

class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

    name = serializers.CharField(min_length=3, error_messages={'required': '該字段必填','min_length':'最短3位'})
    authors = serializers.CharField(required=False)

    # 全局鉤子
    # value是所有效驗(yàn)通過數(shù)據(jù)的字典
    def validate(self, value):
        name=value.get('name')
        price=value.get('price')
        if name and price:
            if str(name)==str(price):
                return value
            else:
                raise ValidationError('名字跟價(jià)格不相等')
        return value

使用postman驗(yàn)證:

Rest Framework:三、HyperlinkedidentityField用法

五、認(rèn)證組件初始

urls.py

url(r'^books/$', views.Books.as_view()),
url(r'^books/(?P<pk>\d+)', views.BooksDetail.as_view()),
url(r'^publish/(?P<pk>\d+)', views.Publish.as_view(), name='ttt'),
url(r'^login/', views.login.as_view()),

app01/server.py (與之前一樣,沒改過)

from rest_framework import serializers
from app01 import models
from rest_framework.exceptions import ValidationError

class AuthorSerializer(serializers.Serializer):
    nid = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'

    name = serializers.CharField(min_length=3, error_messages={'required': '該字段必填','min_length':'最短3位'})
    authors = serializers.CharField(required=False)

    # 局部鉤子
    def validate_name(self,value):
        print(value)
        if value.startswith('sb'):
            raise ValidationError('不能以sb開頭')
        else:
            return value
    # 全局鉤子
    # value是所有效驗(yàn)通過數(shù)據(jù)的字典
    def validate(self, value):
        name=value.get('name')
        price=value.get('price')
        if name and price:
            if str(name)==str(price):
                return value
            else:
                raise ValidationError('名字跟價(jià)格不相等')
        return value

views.py

from django.shortcuts import HttpResponse, render
from rest_framework.views import APIView
from django.http import JsonResponse
from app01 import models
from app01.server import BookSerializer

# Create your views here.
from rest_framework import exceptions


class Auth():
    def authenticate(self, request):
        # 請求來的東西都能拿出來
        # 包裝后的request對象,請求來的所有東西都能拿出來
        # 如果認(rèn)證通過,需要返回東西,如果認(rèn)證不通過,要拋異常
        token = request.GET.get('token')
        ret = models.UserToken.objects.filter(token=token).first()
        # 如果有值,說明登錄過了,而且?guī)У碾S機(jī)字符串也是正確的
        if ret:
            return None
        else:
            # 如果沒有值,拋異常
            raise exceptions.APIException('請登錄')


from rest_framework.request import Request


class BooksDetail(APIView):
    authentication_classes = [Auth]

    def get(self, request, pk):
        response = {'status': 100, 'msg': '成功'}
        ret = models.Book.objects.all().filter(pk=pk).first()
        if ret:
            # 序列化單條,many=False
            book_ser = BookSerializer(ret, many=False)
            print(book_ser.data)
            response['data'] = book_ser.data
        else:
            response['status'] = 101
            response['msg'] = '查詢不存在'
        return JsonResponse(response, safe=False)

    def put(self, request, pk):
        response = {'status': 100, 'msg': '成功'}
        ret = models.Book.objects.all().filter(pk=pk).first()
        if ret:
            # 數(shù)據(jù)校驗(yàn)
            # 傳instance和不傳instance,傳instance的區(qū)別
            # 不傳instance,調(diào)save(),往數(shù)據(jù)庫新增數(shù)據(jù)
            # 傳instance,調(diào)save(),修改數(shù)據(jù)
            ser = BookSerializer(data=request.data, instance=ret)
            if ser.is_valid():
                ser.save()
            else:
                response['status'] = 101
                response['msg'] = ser.errors
        else:
            response['status'] = 102
            response['msg'] = '修改的對象不存在'
        return JsonResponse(response, safe=False)


class Books(APIView):
    def get(self, request, *args, **kwargs):
        ret = models.Book.objects.all()
        book_ser = BookSerializer(ret, many=True, context={'request': request})
        print(book_ser.data)
        return JsonResponse(book_ser.data, safe=False)

    def post(self, request, *args, **kwargs):
        # 前端傳過來的數(shù)據(jù)從data中取
        # 用序列化類的數(shù)據(jù)校驗(yàn)
        # data參數(shù),是要校驗(yàn)的數(shù)據(jù)
        response = {'status': 100, 'msg': '成功'}
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            # 如果數(shù)據(jù)校驗(yàn)通過,is_valid是True
            # 保存到數(shù)據(jù)庫,ser是誰的對象?繼承了ModelSerializer的類的對象
            ser.save()
        else:
            response['status'] = 101
            response['msg'] = ser.errors
        return JsonResponse(response, safe=False)


class Publish(APIView):
    def get(self, request, *args, **kwargs):
        return HttpResponse('ok')


import uuid


class login(APIView):
    def post(self, request):
        response = {'status': 100, 'msg': '登錄成功'}
        name = request.data.get('name')
        pwd = request.data.get('pwd')
        user = models.UserInfo.objects.filter(name=name, pwd=pwd).first()
        if not user:
            response['status'] = 101
            response['msg'] = '用戶名密碼錯(cuò)誤'
        else:
            # 生成一個(gè)隨機(jī)字符串
            token = uuid.uuid4()
            # 去數(shù)據(jù)庫保存
            models.UserToken.objects.create(token=token, user=user)
            response['token'] = token
        return JsonResponse(response, safe=False)

models.py

from django.db import models


# Create your models here.

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    # 外鍵對應(yīng)數(shù)據(jù)庫表中的字段名后面會自動加"_id"        # on_delete=models.CASCADE 級聯(lián)刪除
    publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
    # ManyToManyField 自動創(chuàng)建第三張表,本表名_到你對應(yīng)多的表名名字,自動幫你把表名轉(zhuǎn)小寫
    authors = models.ManyToManyField(to='Author')

    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

    def test(self):
        return self.email
class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)


class UserToken(models.Model):
    token = models.CharField(max_length=64)
    user = models.OneToOneField(to=UserInfo)

python3 manage makemigrations
python3 manage migrate

數(shù)據(jù)庫添加數(shù)據(jù)

Rest Framework:三、HyperlinkedidentityField用法

使用postman 驗(yàn)證:

提交登錄:

Rest Framework:三、HyperlinkedidentityField用法

使用token(已登錄)查詢數(shù)據(jù)信息

Rest Framework:三、HyperlinkedidentityField用法

未登錄顯示:

Rest Framework:三、HyperlinkedidentityField用法

有些健壯性判斷未完成,沒驗(yàn)證用戶是否為登錄狀態(tài)等

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI