Django

[DRF] HyperlinkedModelSerializer 살펴보기

r잡초처럼 2023. 1. 12. 13:33

ModelSerializer에 이어서 HyperlinkedModelSerializer를 살펴보자

  • HyperlinkedModelSerializer는 ModelSerializer와 비슷하다. 단지 관계를 표현할 때  기본 키가 아닌 하이퍼링크로 표현한다는 점을 제외하곤.
  • 기본적으로 serializer에는 기본 키 필드 대신 URL 필드가 포함된다.
  • URL 필드는 HyperlinkedIdentifyField serializer 필드를 사용하여 표현되며 모델의 모든 관계는 HyperlinkedRelatedField serializer 필드를 사용하여 표현된다. 필드 옵션에 추가하여 기본 키를 명시적으로 포함할 수 있다. 예를 들면 아래와 같다.
class AccountSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Account
        fields = ['url', 'id', 'account_name', 'users', 'created']

Absolute and relative URLs

HyperlinkedModelSerializer를 인스턴스화할 때 serializer context에 현재 요청을 포함해야 한다. 예를 들면 다음과 같다.

serializer = AccountSerializer(queryset, context={'request': request})

이렇게 하면 하이퍼링크에 적절한 호스트 이름이 포함되므로 다음과 같이 완전한 URL을 사용한다.

http://api.example.com/accounts/1/

relative URL은 다음과 같다.

/accounts/1/

상대 URL을 사용하려면 serailizer context에서 {'request': None}을 명시적으로 전달해야 한다.

How hyperlinked views are determined

모델 인스턴스에 대한 하이퍼링크를 위해 어떤 뷰를 사용해야 하는지 결정하는 방법이 필요하다. 기본적으로 하이퍼링크는 '{model_name}-detail'과 일치하는 view_name에 해당해야 하며 pk 키워드 인수로 인스턴스를 조회한다. extra_kwargs 설정에서 view_namelookup_field 옵션 중 하나 또는 둘 모두를 사용하며 URL 필드 view_name 및 조회 필드를 재정의할 수 있다.

class AccountSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Account
        fields = ['account_url', 'account_name', 'users', 'created']
        extra_kwargs = {
            'url': {'view_name': 'accounts', 'lookup_field': 'account_name'},
            'users': {'lookup_field': 'username'}
        }

또는 필드에서 명시적으로 설정할 수 있다.

class AccountSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(
        view_name='accounts',
        lookup_field='slug'
    )
    users = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        lookup_field='username',
        many=True,
        read_only=True
    )

    class Meta:
        model = Account
        fields = ['url', 'account_name', 'users', 'created']