У меня есть обычный ModelViewSet для одной из моих моделей, но я хочу иметь возможность указать конкретный ПК для создания нового экземпляра.Например, если бы я отправил:
{
"name": "Name"
}
Было бы получить случайный pk.Но если я отправлю:
{
"id": "123",
"name": "Name"
}
Я хочу, чтобы у него был указанный pk (id).
Подобно этому человеку, что я сделал, это добавил *Поле 1011 * для моего ModelSerializer выглядит следующим образом:
class ConversationViewSet(viewsets.ModelViewSet):
"""
List all conversations, or create new / edit existing product.
"""
queryset = Conversation.objects.all()
serializer_class = ConversationSerializer
class ConversationSerializer(serializers.ModelSerializer):
id = serializers.CharField(required=False) # Instead of serializer.ReadOnlyField()
class Meta:
model = Conversation
fields = '__all__'
Хотя это работает для метода create
, оно вызывает проблемы для update
и partial_update
, где id
теперь требуетсяаргумент в качестве параметра строки запроса и в теле запроса, подобном этому (из документов):
update
PUT /conversations/{id}/
Update existing conversation.
Path Parameters
The following parameters should be included in the URL path.
Parameter Description
id (required) A unique value identifying this conversation.
Request Body
The request body should be a "application/json" encoded object, containing the following items.
Parameter Description
id
access_token
username
password
app_user_id
name
Использование двух параметров с одинаковым именем, конечно, является плохой практикой.Например, при использовании requests
и передаче словаря параметров он больше не работает, потому что не знает, к какому параметру я обращаюсь.
Как я могу это исправить так, чтобы параметр id
былнеобязательно только для метода create
, но все остальные методы (list, read, ...) остаются такими же, как в случае по умолчанию?
Мое решение
, основываясь на ответе JPG, я изменил свой сериализатор так:
class ConversationSerializer(serializers.ModelSerializer):
id = serializers.ReadOnlyField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.context['view'].action == 'create':
self.fields['id'] = serializers.CharField(required=False)
class Meta:
model = Conversation
fields = '__all__'