Я работаю над разработкой API с Django-rest-framework и потреблением его из веб-приложения. Он имеет модель врача с Fk из модели пользователя django.auth. Я хочу отправить сообщение из формы в модель врача, но сериализатор возвращает это сообщение:
{ "user": { "non_field_errors": [ "Недопустимые данные. Ожидаемый словарь, но получил unicode." ]}}
Я посылаю первичный ключ объекта пользователя. Что является правильным (или только одним способом) для хранения внешнего ключа на DRF. Я попытался переопределить get_validation_exclusions на сериализаторе и переопределить метод execute_create в представлении.
Api и веб-приложение развязаны. API разработан с помощью django и веб-приложения с угловыми функциями.
Моя модель
class Physician(models.Model):
medical_office_number = models.CharField(max_length = 15)
fiscal_id_number = models.CharField(max_length = 20)
user = models.OneToOneField(User)
def __unicode__(self):
return self.user.first_name +' '+ self.user.last_name
Serializer:
class PhysicianSerializer(serializers.ModelSerializer):
user = AccountSerializer()
class Meta:
model = Physician
fields = ('id', 'user', 'medical_office_number', 'fiscal_id_number')
read_only_fields = ('id')
depth = 1
def get_validation_exclusions(self, *args, **kwargs):
exclusions = super(PhysicianSerializer, self).get_validation_exclusions()
return exclusions + ['user']
* Редактировать Это мой сериализатор учетных записей, который основан на этой реализации и с предложением @Kevin Brown
class PrimaryKeyNestedMixin(serializers.RelatedField, serializers.ModelSerializer):
def to_internal_value(self, data):
return serializers.PrimaryKeyRelatedField.to_internal_value(self, data)
def to_representation(self, data):
return serializers.ModelSerializer.to_representation(self, data)
class AccountSerializer(PrimaryKeyNestedMixin):
password = serializers.CharField(write_only=True, required=False)
confirm_password = serializers.CharField(write_only=True, required=False)
class Meta:
model = Account
fields = ('id', 'email', 'username', 'created_at', 'updated_at',
'first_name', 'last_name', 'password',
'confirm_password', 'is_admin',)
read_only_fields = ('created_at', 'updated_at',)
Viewset
class AccountViewSet(viewsets.ModelViewSet):
lookup_field = 'username'
queryset = Account.objects.all()
serializer_class = AccountSerializer
Когда я пытаюсь выполнить сериализацию этого объекта, он вызывает ошибку.
Поэтому я могу опубликовать любого пользователя из элемента <select>
. Но я не могу проверить решение. Что-то мне не хватает?
Ошибка Stacktrace
TypeError at /api/v1/accounts/
__init__() takes exactly 1 argument (5 given)
Exception Location: /home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/relations.py in many_init, line 68
Python Executable: /home/jlromeroc/workspace/asclepios/venv/bin/python
Python Version: 2.7.3
File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 111. response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view 57. return view_func(*args, **kwargs)
File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view 85. return self.dispatch(request, *args, **kwargs)
File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch 407. response = self.handle_exception(exc) File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch 404. response = handler(request, *args, **kwargs)
File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/mixins.py" in list 45. serializer = self.get_serializer(instance, many=True)
File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/generics.py" in get_serializer 90. instance, data=data, many=many, partial=partial, context=context File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/relations.py" in __new__ 48. return cls.many_init(*args, **kwargs)
File "/home/jlromeroc/workspace/asclepios/venv/local/lib/python2.7/site-packages/rest_framework/relations.py" in many_init 68. list_kwargs = {'child_relation': cls(*args, **kwargs)}
Exception Type: TypeError at /api/v1/accounts/
Exception Value: __init__() takes exactly 1 argument (5 given)
Изменить ** Я решил переопределить функцию create в представлении и включить объект в запрос, чтобы его можно было проверить, но затем сериализатор пытается вставить новый объект для модели Account. Как я могу предотвратить это поведение? Я попытался установить сериализатор класса PhysicianSerializer как read_only, но затем django пытается сохранить модель с нулевым user_id. Как сохранить модель без попытки вставки связанного объекта?