ビルドドジャンゴレストAPI


この記事では、ユーザー認証を使用して既存のDjango REST APIにCRUD(作成、読み取り、更新、削除)機能を追加します.これは、私たちが登録、ログイン、ログアウトのような認証機能を追加した前の記事の続きです{"message": "Welcome to the BookStore!"} そして、ユーザは我々の終点にアクセスするために認証されなければなりません.
しますか



  • 始めましょう😀
    我々はいくつかのモデルを作成することから始めましょう.Djangoモデルは、基本的にデータにアクセスして、管理する際に利用されるPythonオブジェクトです.モデルは、フィールドの種類のような格納されたデータの構造を定義し、データ間の関係を作成し、特定の制約をデータフィールドに適用し、さらに多くのものを定義します.Djangoモデルの詳細についてはdocumentation V 3.
    我々のためにbookstore_app , つのモデルを作成しますAuthor and Book .
    # ./bookstore_app/api/models.py
    
    from django.db import models
    from django.conf import settings
    from django.utils import timezone
    
    # Create your models here.
    class Author(models.Model):
      name = models.CharField(max_length=200)
      added_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
      created_date = models.DateTimeField(default=timezone.now)
    
      def __str__(self):
        return self.name
    
    class Book(models.Model):
      title = models.CharField(max_length=200)
      description = models.CharField(max_length=300)  
      author = models.ForeignKey(Author, on_delete=models.CASCADE)
      added_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
      created_date = models.DateTimeField(default=timezone.now)
    
      def __str__(self):
        return self.title
    
    
    何かが我々が作成したモデルに注意してください:
  • Book モデルは、本の著者が必要です.だから我々はフィールドを作成author を参照してくださいAuthor モデル.
  • 我々はどちらかのエントリを追加したユーザーを追跡したいBook or Author , だから我々はフィールドを作成するadded_by を参照してくださいAUTH_USER_MODEL .
  • 今私たちのモデルを作成して、我々は移動を実行する必要があります.でもその前にmakemigrations その後、作成された移行を実行します.
    $ python manage.py makemigrations
    $ python manage.py migrate
    
    テストドライブの時間🚀. 私は、Djangoで新しくつくられたモデルをテストしていますshell エントリを追加するAuthor . 端末では、実行してシェルを起動しましょうpython manage.py shell .
    $ python manage.py shell
    Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
    [GCC 8.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>>
    
    中でフィールドを見ることAuthor モデル、
  • name : これは最大長200の文字フィールドです.
  • added_by : ユーザモデルを参照する.新しいエントリを作るためには、ユーザのインスタンスを渡す必要があります.
  • created_date : デフォルトは現在のエントリ時刻です.
  • だから、shell 我々は、インポートする必要がありますUser and Author モデルにエントリを追加するAuthor 可能です.
    >>> from django.contrib.auth.models import User
    >>> from api.models import Author
    

    ユーザを作成しましょう
    まず、ユーザーのインスタンスを作成し、モデルに保存メソッドを呼び出してDBに保存します.
    >>> user = User(first_name="John", last_name="Doe", username="johndoe")
    >>> user.save()
    

    作者の追加
    著者を追加するには、著者のインスタンスを作成し、既に作成したユーザーのインスタンスを渡しますadded_by
    >>> author1 = Author(name="Author Mie", added_by=user)
    >>> author1.save()
    >>> author2 = Author(name="Author Mello", added_by=user)
    >>> author2.save()
    
    我々は正常に2つの新しい著者を追加しました.著者表のすべてのエントリを取得するには、次の手順に従います
    >>> Author.objects.all()
    <QuerySet [<Author: Author Mie>, <Author: Author Mello>]>
    
    また、私たちのモデルを使用することができますDjango管理インターフェイスを使用して提供されるhttps://localhost:8000/admin . しかし、我々がそうする前に、我々は最初になければなりません:
  • 管理インターフェイスにモデルを追加
  • スーパーユーザーの作成

  • モデルを管理インターフェイスに追加するには
    # bookstore_app/api/admin.py
    
    from django.contrib import admin
    from .models import Author, Book
    
    # Register your models here.
    admin.site.register(Author)
    admin.site.register(Book)
    

    スーパーユーザーを作成するには

    A "superuser" account has full access to the server and all needed permissions.


    端末上で実行するpython manage.py createsuperuser
    $ python manage.py createsuperuser
    Username: superadmin
    Email address: [email protected]
    Password: 
    Password (again):
    
    Superuser created successfully.
    
    スーパーユーザを作成しました.次に、作成したSuperUser資格情報を使用して、ブラウザ上のサーバーとログインをブラウザ上で管理します.ログイン成功後、あなたの管理インターフェイスは以下の画像のようになります.今より多くの著者や書籍を追加することができますも許可を設定すると、特定のユーザーを無効にする必要がある場合はもっとたくさん.もちろん、あなたはsuperuser !!!
    https://localhost:8000/admin

    これまでのところ、我々はデータを永続化し、シェル上のDBから読みこむことができました.これは、サーバーをポスト、取得、プット、削除要求を処理するいくつかのビューを作成する時間です.しかし、我々は新しいビューを追加する前にapi/views.py ファイル、私たちのモデルのためのserializersを作成しましょう.

    Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON.


    シリアルライタを作成するにはserializers.py ファイルをapi アプリケーションのフォルダを作成しAuthorSerializer and BookSerializer , 我々が応答に渡す異なるモデルで我々が気にかける分野を選ぶこと.
    # bookstore_app/api/serializers.py
    
    from rest_framework import serializers
    from .models import Author, Book
    
    class AuthorSerializer(serializers.ModelSerializer):
        class Meta:
            model = Author
            fields = ['id', 'name', 'added_by', 'created_by']
    
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = Book
            fields = ['id', 'title', 'description', 'created_date', 'author', 'added_by']
    
    
    我々は、我々のserializer準備ができて、開けましょうapi/views.py ファイル.ファイルの現在の内容は前のポストからなければなりません.
    # ./bookstore_app/api/views.py
    
    from rest_framework.decorators import api_view, permission_classes
    from rest_framework.permissions import IsAuthenticated
    from django.http import JsonResponse
    from django.views.decorators.csrf import csrf_exempt
    
    @api_view(["GET"])
    @csrf_exempt
    @permission_classes([IsAuthenticated])  
    def welcome(request):
        content = {"message": "Welcome to the BookStore!"}
        return JsonResponse(content)
    

    ユーザーはすべての書籍を得ることができます
    # ./bookstore_app/api/views.py
    
    ...
    from .serializers import BookSerializer
    from .models import Book
    from rest_framework import status
    
    
    @api_view(["GET"])
    @csrf_exempt
    @permission_classes([IsAuthenticated])
    def get_books(request):
        user = request.user.id
        books = Book.objects.filter(added_by=user)
        serializer = BookSerializer(books, many=True)
        return JsonResponse({'books': serializer.data}, safe=False, status=status.HTTP_200_OK)
    

    ユーザーは本を追加できます
    # ./bookstore_app/api/views.py
    
    ...
    from .models import Book, Author
    import json
    from django.core.exceptions import ObjectDoesNotExist
    
    @api_view(["POST"])
    @csrf_exempt
    @permission_classes([IsAuthenticated])
    def add_book(request):
        payload = json.loads(request.body)
        user = request.user
        try:
            author = Author.objects.get(id=payload["author"])
            book = Book.objects.create(
                title=payload["title"],
                description=payload["description"],
                added_by=user,
                author=author
            )
            serializer = BookSerializer(book)
            return JsonResponse({'books': serializer.data}, safe=False, status=status.HTTP_201_CREATED)
        except ObjectDoesNotExist as e:
            return JsonResponse({'error': str(e)}, safe=False, status=status.HTTP_404_NOT_FOUND)
        except Exception:
            return JsonResponse({'error': 'Something terrible went wrong'}, safe=False, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    

    ユーザーはIDでブックエントリを更新することができます
    # ./bookstore_app/api/views.py
    
    ...
    @api_view(["PUT"])
    @csrf_exempt
    @permission_classes([IsAuthenticated])
    def update_book(request, book_id):
        user = request.user.id
        payload = json.loads(request.body)
        try:
            book_item = Book.objects.filter(added_by=user, id=book_id)
            # returns 1 or 0
            book_item.update(**payload)
            book = Book.objects.get(id=book_id)
            serializer = BookSerializer(book)
            return JsonResponse({'book': serializer.data}, safe=False, status=status.HTTP_200_OK)
        except ObjectDoesNotExist as e:
            return JsonResponse({'error': str(e)}, safe=False, status=status.HTTP_404_NOT_FOUND)
        except Exception:
            return JsonResponse({'error': 'Something terrible went wrong'}, safe=False, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    

    ユーザーはIDでブックエントリを削除できます
    # ./bookstore_app/api/views.py
    
    ...
    
    @api_view(["DELETE"])
    @csrf_exempt
    @permission_classes([IsAuthenticated])
    def delete_book(request, book_id):
        user = request.user.id
        try:
            book = Book.objects.get(added_by=user, id=book_id)
            book.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        except ObjectDoesNotExist as e:
            return JsonResponse({'error': str(e)}, safe=False, status=status.HTTP_404_NOT_FOUND)
        except Exception:
            return JsonResponse({'error': 'Something went wrong'}, safe=False, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    ビューとその機能性を完了した、我々は今、それらを追加しますapi/urls.py ファイル.
    # ./bookstore_app/api/urls.py
    
    from django.urls import include, path
    from . import views
    
    urlpatterns = [
      ...
      path('getbooks', views.get_books),
      path('addbook', views.add_book),
      path('updatebook/<int:book_id>', views.update_book),
      path('deletebook/<int:book_id>', views.delete_book)
    ]
    
    さあ、環境とDjangoサーバを始めましょう.アクセスするmanage.py ファイルは、Djangoプロジェクトにする必要がありますbookstore_app ディレクトリ.
    $ cd bookstore_app
    $ pipenv shell
    $ python manage.py runserver
    
    使えますPostman 同じJSONプロパティでテストするにはcurl .

    テストを始めよう😀
    新規ユーザ登録
    ユーザーを作成するにはPOST リクエストlocalhost:8000/registration/ フィールドを渡すusername , password1 , password2 , あなたは、1を渡すほうを選ぶかもしれませんemail フィールドが、オプションです.
    > Request
    
    $ curl -X POST -H "Content-Type: application/json" -d '{"username":"testuser", "password1":"testpassword", "password2":"testpassword"}' localhost:8000/registration/
    
    > Response:
       {"key":"1565c60a136420bc733b10c4a165e07698014acb"}
    
    また、ログイン後に認証トークンを取得しますlocalhost:8000/login/ 通過フィールドusername and password . エンドポイントの残りの部分をテストするには、我々が有効な認証済みユーザであることをサーバに証明する必要があります.それで、これをするために、我々は我々が登録の後、得たトークンをセットしますAuthorization プロパティHeaders dict実際のトークンを事前に修正するToken .
    Authorization: Token 1565c60a136420bc733b10c4a165e07698014acb
    
    新しい本を加える
    本を追加するにはPOST リクエストlocalhost:8000/api/addbook 通過フィールドtitle , description , author (以前に作成した著者のID)
    > Request
    $ curl -X POST -H "Authorization: Token 1565c60a136420bc733b10c4a165e07698014acb" -d '{"title":"CRUD Django", "description":"Walkthrough for CRUD in DJANGO", "author": 1}' localhost:8000/api/addbook 
    
    > Response
       {"book": {
           "id": 1, 
           "title": "CRUD Django", 
           "description": "Walkthrough for CRUD in DJANGO", 
           "author": 1, 
           "added_by": 2, 
           "created_date": "2020-02-29T21:07:27.968463Z"
         }
       }
    
    すべての本を得る
    すべての本を得るために、私たちはGET Localhostへのリクエスト:8000/API/getbooks.これは、現在ログインしているユーザーによって加えられたすべての本のリストを与えます.
    > Request
    $ curl -X GET -H "Authorization: Token 9992e37dcee4368da3f720b510d1bc9ed0f64fca" -d '' localhost:8000/api/getbooks
    
    > Response
    {"books": [
          {
            "id": 1, 
            "title": "CRUD Django", 
            "description": "Walkthrough for CRUD in DJANGO", 
            "author": 1, 
            "added_by": 2, 
            "created_date": "2020-02-29T21:07:27.968463Z"
           }
        ]
     }  
    
    IDでブックエントリを更新する
    本を更新するにはPUT を渡すリクエストid URLのパラメータとして更新したいlocalhost:8000/api/updatebook/<id> 渡すフィールドを変更するフィールド.
    > Request
    $ curl -X PUT -H "Authorization: Token 9992e37dcee4368da3f720b510d1bc9ed0f64fca" -d '{"title":"CRUD Django Updated V2", "description":"Walkthrough for CRUD in DJANGO", "author": 1}' localhost:8000/api/updatebook/1
    
    > Response
    {"book": {
        "id": 1, 
        "title": "CRUD Django Updated V2", 
        "description": "Walkthrough for CRUD in DJANGO", 
        "author": 1, 
        "added_by": 2, 
        "created_date": "2020-02-29T21:07:27.968463Z"
      }
    }  
    
    本エントリをIDで削除
    本を削除するにはDELETE を渡すリクエストid URLのパラメータとして削除したいlocalhost:8000/api/deletebook/<id>
    > Request
    $ curl -X DELETE -H "Authorization: Token 9992e37dcee4368da3f720b510d1bc9ed0f64fca" -d '' localhost:8000/api/deletebook/1  
    
    ハーレイ🎉🎉, 我々は完全に機能的なDjangoの残りのAPIを機能している.Postmanを使ってテストしている場合は、エラー応答{ "detail": "CSRF Failed: CSRF token missing or incorrect." } , クリアリングCookies Postmanで問題を修正します.
    最後の2つの(2)ポストとこのポストのためのすべての我々のコード:



  • このgithubリポジトリに存在する.Bookstore Django REST API
    お読みありがとうございます.😃