Django REST Framework: когда создавать гиперссылки ресурса и при вложенном ресурсе? Как установить POST вложенный ресурс?

Я создаю веб-API REST с помощью Django REST Framework. Все идет хорошо, но я, однако, наткнулся на проблему с вложенными ресурсами. Сначала все отношения в REST API были связаны гиперссылками. Сообщение, например, выглядело так:

{
    "path": "http://api.myproject.com/posts/1.json",
    "id": 1,
    "author": "http://api.myproject.com/users/broak.json",
    "image": "/images/posts/cxyUzlPo.jpg",
    "header": "Who am I?",
    "footer": "I am a champion!",
    "date": "2014-11-09 15:16",
    "likes": "http://api.myproject.com/posts/1/likes.json",
    "comments": "http://api.myproject.com/posts/1/comments.json",
    "likes_count": 0,
    "comments_count": 0
}

Связь между сообщением и автором (пользователем) связана с гиперссылкой. Когда вы хотите создать новое сообщение, вам нужно указать правильную гиперссылку для конкретного пользователя - это отлично работает.

При вызове списка сообщений все становится неэффективным, потому что вы должны сделать дополнительный вызов API для каждого автора для каждого сообщения. Я решил это, используя ресурсы NESTED вместо ресурсов HYPERLINKED, поэтому каждый пост теперь содержит всю информацию об авторе.

{
    "path": "http://api.myproject.com/posts/1.json",
    "id": 1,
    "author": {
        "email": "[email protected]"
        "username": "broak",
        "first_name: "John",
        "last_name": "Broak",
        "is_staff": False,
        "is_active": True,
        "last_login": "02-26-2016"
    },
    "image": "/images/posts/cxyUzlPo.jpg",
    "header": "Who am I?",
    "footer": "I am a champion!",
    "date": "2014-11-09 15:16",
    "likes": "http://api.myproject.com/posts/1/likes.json",
    "comments": "http://api.myproject.com/posts/1/comments.json",
    "likes_count": 0,
    "comments_count": 0
}

Мой первый вопрос: есть ли у вас руководство, должен ли я создавать вложенную структуру данных или отдельную конечную точку с гиперссылкой на нее.

Мой второй вопрос: когда я использую автора в качестве вложенного ресурса и хочу создать новое сообщение, я не хочу указывать всю информацию об авторе (имя пользователя, адрес электронной почты,...). Есть ли способ использовать ссылку для пользователя для операции CREATE/UPDATE? Или изменить что-то, чтобы идентификатор пользователя был достаточно, чтобы заполнить это поле?

Ответ 1

Если я правильно понял ваш вопрос, вы хотите расширить автора во время получения данных и просто хотите отправить идентификатор или URL-адрес в случае обновления и создания.

1# Это не о каких-либо рекомендациях, и это полностью зависит от вашего требования о том, как будет использоваться ваш api.

2# Поэтому вам нужно расширить UserSerializer и переопределить to_internal_value. Пример кода может выглядеть как

class MyCustomSerializer(UserSerializer):
    def to_internal_value(self, data):
        # data must be valid user-detail url
        return serializers.HyperLinkedRelatedField(queryset=User.objects.all(), view_name='user-detail').to_internal_value(data)

Обратите внимание на, что для работы с HyperLinkedRelatedField у вас должна быть конечная точка для детализации пользователя.

Итак, если вы хотите отправить ID, то пример кода может выглядеть как

class MyCustomSerializer(UserSerializer):
    # data must be valid user id
    def to_internal_value(self, data):
        return serializers.PrimaryKeyRelatedField(queryset=User.objects.all()).to_internal_value(data)

Однако я хотел бы сохранить последовательность отправки поля ForeignKey в POST/PUT/PATCH. (Всегда либо URL, либо ID).

затем используйте его в своем коде, например

class PostSerializer(serializers.HyperlinkedModelSerializer):
    author = MyCustomSerializer()

    class Meta:
        model = Post

См. документацию Writable вложенных сериализаторов на POST на вложенном ресурсе.