Sto lavorando allo sviluppo di un'API con Django-rest-framework e consumo da un'app Web. Ha un modello di medico con un Fk dal modello utente django.auth. Voglio inviare da un modulo per il modello medico, ma il serializzatore restituisce questo messaggio:SerializerClass field on Serializer save from primary key
{ "utente": { "non_field_errors": [ ". Dati non validi attesi un dizionario, ma ha ottenuto unicode"]} }
Sto inviando la chiave primaria dell'oggetto utente. Qual è il giusto (o solo un modo) per memorizzare una chiave esterna su DRF. Ho provato a sovrascrivere get_validation_exclusions sul serializzatore e a sovrascrivere il metodo perform_create sul gruppo di viste.
L'api e l'app Web sono scollegate. L'API è sviluppata con django e l'app web con angularjs.
Il mio modello
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']
* Modifica Questo è il mio conto serializzatore, che si basa su questa implementazione e con il suggerimento @ 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
Quando si tenta di serializzare questo oggetto, si genera un errore.
Così posso postare qualsiasi utente dall'elemento <select>
. Ma non posso verificare la soluzione. Qualcosa che mi manca?
errore 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)
Edit ** ho scelto di ignorare la funzione di creare sul viewset e includere l'oggetto nella richiesta, in modo che può essere convalidato, ma poi, il serializzatore cerca di inserire un nuovo oggetto per il modello Account. Come posso prevenire questo comportamento? Ho provato a impostare il serializzatore sulla classe PhysicianSerializer come read_only, ma django tenta di memorizzare il modello con un user_id null. Come posso salvare un modello senza provare a inserire anche un oggetto correlato?
e questo è valido per tutti i serializzatori che sono un fk su un altro serializzatore? Sembra un approccio strano per una situazione abbastanza normale. se hai un
In entrambi i casi, la tua risposta sembra promettente. Grazie – Cheluis
Non funziona, ho ottenuto che il campo Relazionale fornisca un argomento 'queryset', o set read_only =' True'. se uso la classe Serializer come un campo. – Cheluis