Django REST 필터링 자습서 - 소개(1부)

앙트레



이 튜토리얼에서는 Django REST 필터링 개념과 내가 일반적으로 사용하고 가르치는 일반적인 예를 수집하는 것을 목표로 합니다. 그 중 일부는 공식 Django REST 문서에서 찾을 수 있지만 샘플 리포지토리를 살펴보겠습니다.

리포지토리는 가능한 적은 코드로 구성되며 이는 API 버전 관리(api/v1), The Twelve Factor App 등과 같은 모범 사례에 따라 설계되지 않았음을 의미합니다.

NOTE

You can find the code we're working on this tutorial series in this repository: django-rest-filtering-tutorial

You don't need to download and setup the repository in order to follow this series, however I'd like to encorauge to do so, since while you play you learn better as always.



레포 설정



위에서 언급했듯이 저장소를 설정할 필요는 없지만 원하는 경우 아래 명령을 실행하는 것이 좋습니다.

# Create virtual environment named .venv
$ python -m venv ./.venv
# Activate the virtual environment
$ source ./.venv/bin/activate
# Install python packages
$ python -m pip install -r requirements.txt
# Create db, make migrations and seed database with some dummy data
$ python populate_db.py
# Run development server
$ python manage.py runserver 8000
# or
# ./manage.py runserver 8000


INFO

You don't need to give 8000 port since it's 8default port but I always prefer verbosity.



또 다른 옵션은 gnu make을 사용하고 간단히 실행할 수 있다는 것입니다.

$ make start


이 make 대상은 위의 모든 명령을 함께 실행하므로 저장소를 설정하고 개발 서버를 실행합니다.

HTTP 요청 보내기



HTTP 요청에 대해 httpie을 사용할 것입니다. 더 인간이 사용할 수 있기 때문입니다. 또는 더 개발자 친화적이라고 합시다. 다채로운 구문 강조 표시(멋진 JSON 출력과 같은), 영구 세션, 파일 다운로드 기능 등을 제공하며 Python으로 작성되었지만 curl도 사용할 수 있습니다.

$ http GET http://localhost:8000/authors/
# or with less keystroke, it's same as above
$ http :8000/authors/
# curl equivalent
$ curl http://localhost:8000/authors/


자세한 내용은 httpie doc을 참조하십시오.



몇 가지 기본 사항부터 시작하여 끝점에 http 요청을 보냅니다.

모든 작성자를 가져오려면 다음을 실행하십시오.

$ http :8000/authors/

HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 165
Content-Type: application/json
Date: Fri, 17 Mar 2022 11:03:37 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.8.11
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

[
    {
        "first_name": "Name1",
        "full_name": "Name1 Surname1",
        "id": 1,
        "last_name": "Surname1",
        "user": null
    },
    {
        "first_name": "Name2",
        "full_name": "Name2 Surname2",
        "id": 2,
        "last_name": "Surname2",
        "user": null
    },
    {
        "first_name": "Name2",
        "full_name": "Name2 Surname2",
        "id": 3,
        "last_name": "Surname2",
        "user": 3
    }
]


저자 뒤의 슬래시( / ) 접미사에 유의하십시오. 추가하지 않으면 다음을 얻게 됩니다.

$ http :8000/authors

HTTP/1.1 301 Moved Permanently
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Fri, 17 Mar 2022 11:05:35 GMT
Location: /authors/
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.8.11
X-Content-Type-Options: nosniff


기본적으로 --follow에 있는 httpie의 구성 파일에 ~/.config/httpie/config.json 인수를 플래그 또는 구성으로 추가하여 이 동작을 변경할 수 있습니다. 명령 플래그로:

$ http :8000/authors --follow


구성으로:

// ~/.config/httpie/config.json
{
    "__meta__": {
        "about": "HTTPie configuration file",
        "help": "https://httpie.org/doc#config",
        "httpie": "1.0.3"
    },
    "default_options": [
        "--timeout=300",
        "follow"
    ]
}


Django는 APPEND_SLASH 설정을 통해 이 동작을 제어합니다.

APPEND_SLASH

Default: True

When set to True, if the request URL does not match any of the patterns in the URLconf and it doesn’t end in a slash, an HTTP redirect is issued to the same URL with a slash appended. Note that the redirect may cause any data submitted in a POST request to be lost.

The APPEND_SLASH setting is only used if CommonMiddleware is installed (see Middleware). See also PREPEND_WWW.



또한 응답에서 header 부분을 생략하려면 --body 플래그를 제공하십시오.

기본 필터링



Django REST에 대한 기본 필터는 필터가 없습니다. 즉, 데이터베이스에서 모든 개체를 반환합니다.

즉, 일부 매개 변수를 사용하여 끝점을 필터링하려고 하면 위와 같이 모든 개체가 함께 반환됩니다.

$ http ":8000/authors/?id=1"

[
    {
        "first_name": "Name1",
        "full_name": "Name1 Surname1",
        "id": 1,
        "last_name": "Surname1",
        "user": null
    },
    {
        "first_name": "Name2",
        "full_name": "Name2 Surname2",
        "id": 2,
        "last_name": "Surname2",
        "user": null
    },
    {
        "first_name": "Name2",
        "full_name": "Name2 Surname2",
        "id": 3,
        "last_name": "Surname2",
        "user": 3
    }
]


더 나은 이해를 위해 소스 코드에서 책임 있는get_queryset 메서드를 살펴보겠습니다.

# rest_framework/generics.py
def get_queryset(self):
    """
    Get the list of items for this view.
    This must be an iterable, and may be a queryset.
    Defaults to using `self.queryset`.

    This method should always be used rather than accessing `self.queryset`
    directly, as `self.queryset` gets evaluated only once, and those results
    are cached for all subsequent requests.

    You may want to override this if you need to provide different
    querysets depending on the incoming request.

    (Eg. return a list of items that is specific to the user)
    """
    assert self.queryset is not None, (
        "'%s' should either include a `queryset` attribute, "
        "or override the `get_queryset()` method."
        % self.__class__.__name__
    )

    queryset = self.queryset
    if isinstance(queryset, QuerySet):
        # Ensure queryset is re-evaluated on each request.
        queryset = queryset.all()
    return queryset


보시다시피 관련 보기에서 queryset 속성을 반환하며 이 경우에는 Article.objects.all()입니다.

# src/articles/view.py
from rest_framework import viewsets

from src.articles.models import Article
from src.articles.serializers import ArticleSerializer


class ArticleViewSet(viewsets.ModelViewSet):
    serializer_class = ArticleSerializer
    queryset = Article.objects.all()


예를 들어 queryset 속성을 Article.objects.filter(content__icontains="3")로 변경하면

# src/articles/view.py
from rest_framework import viewsets

from src.articles.models import Article
from src.articles.serializers import ArticleSerializer


class ArticleViewSet(viewsets.ModelViewSet):
    serializer_class = ArticleSerializer
    queryset = Article.objects.filter(content__icontains="3")


가짜 Article3 기사만 반환합니다.

$ http ":8000/authors/"
# or
$ http ":8000/authors/?id=1"

[
    {
        "author": 3,
        "content": "Fake Content3",
        "id": 3,
        "regions": [],
        "title": "Fake Article3"
    }
]


동시에 get_queryset 메소드를 직접 변경하고 queryset 속성을 던질 수 있음을 알 수 있습니다.

# src/articles/views.py
class ArticleViewSet(viewsets.ModelViewSet):
    serializer_class = ArticleSerializer

    def get_queryset(self):
        return Article.objects.filter(content__icontains="3")


결론



이것이 시리즈의 이 부분에 대한 전부입니다. 다음 부분에서는 보다 심도 있는 예제와 사례를 살펴보겠습니다.

모두 끝났습니다!

좋은 웹페이지 즐겨찾기