2014-11-13 4 views
10

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

{ 
    "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? Или изменить что-то, чтобы идентификатор пользователя был достаточно, чтобы заполнить это поле?

ответ

7

Если я правильно понял ваш вопрос, вы хотите расширить автора во время получения данных и просто хотите отправить идентификатор или 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 nested serializers к POST на вложенный ресурсе.