16

से Serializer से SerializerClass फ़ील्ड से बचें मैं Django-rest-framework के साथ एक एपीआई विकसित करने और इसे वेब ऐप से उपभोग करने में काम कर रहा हूं। इसमें django.auth उपयोगकर्ता मॉडल से FK के साथ एक चिकित्सक मॉडल है। मैं एक रूप से चिकित्सकों की मॉडल को पोस्ट करने के लिए चाहते हैं, लेकिन serializer इस संदेश देता है:प्राथमिक कुंजी

{ "उपयोगकर्ता": { "non_field_errors": [ "।। अमान्य डेटा एक शब्दकोश अपेक्षित हैं, लेकिन यूनिकोड मिला"]} }

मैं उपयोगकर्ता ऑब्जेक्ट की प्राथमिक कुंजी भेज रहा हूं। डीआरएफ पर एक विदेशी कुंजी स्टोर करने के लिए सही (या सिर्फ एक तरफ) कौन सा है। मैंने serializer पर get_validation_exclusions को ओवरराइड करने और विचारों पर perform_create विधि को ओवरराइड करने का प्रयास किया है।

एपीआई और वेब ऐप decouple हैं। एपीआई django और angularjs के साथ वेब ऐप के साथ विकसित किया गया है।

मेरे मॉडल

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'] 

* संपादित यह मेरा खाता serializer है, जो इस कार्यान्वयन पर और @Kevin ब्राउन सुझाव

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',) 
साथ आधारित है

व्यूसेट

class AccountViewSet(viewsets.ModelViewSet): 
    lookup_field = 'username' 
    queryset = Account.objects.all() 
    serializer_class = AccountSerializer 

जब मैं इस ऑब्जेक्ट को क्रमबद्ध करने का प्रयास करता हूं, तो यह एक त्रुटि को ट्रिगर करता है।

तो मैं किसी भी उपयोगकर्ता को <select> तत्व से पोस्ट कर सकता हूं। लेकिन मैं समाधान की पुष्टि नहीं कर सकता। मुझे कुछ याद आ रही है?

त्रुटि स्टैकट्रेस

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) 

संपादित ** मैं viewset पर बनाने के समारोह को ओवरराइड और अनुरोध में वस्तु को शामिल करने का विकल्प चुना है, तो यह मान्य किया जा सकता है, लेकिन फिर, serializer डालने की कोशिश करता है खाता मॉडल के लिए एक नई वस्तु। मैं इस व्यवहार को कैसे रोक सकता हूं? मैंने readianererializer वर्ग पर serializer को read_only के रूप में सेट करने का प्रयास किया लेकिन फिर, django मॉडल को एक शून्य उपयोगकर्ता_आईडी के साथ स्टोर करने का प्रयास करता है। मैं संबंधित ऑब्जेक्ट को सम्मिलित करने के बिना मॉडल को कैसे सहेज सकता हूं?

उत्तर

3

यहां मुद्दा यह है कि नेस्टेड धारावाहिकों के साथ, Django REST ढांचे इनपुट और आउटपुट दोनों को घोंसला प्रस्तुत करने की उम्मीद कर रहा है। डीआरएफ स्वचालित रूप से यह सुनिश्चित करने के लिए इनपुट को मान्य करेगा कि यह नेस्टेड धारावाहिक से मेल खाता है, जिससे आप मुख्य ऑब्जेक्ट और किसी भी अनुरोध को किसी भी अनुरोध में बना सकते हैं।

आप PrimaryKeyRelatedField इनपुट के साथ एक नेस्टेड आउटपुट देखना चाहते हैं। यह उन लोगों के लिए बहुत आम है जिन्हें एक ही अनुरोध में संबंध बनाने की आवश्यकता नहीं है, बल्कि इसके बजाय हमेशा अपने संबंधों में मौजूदा वस्तुओं का उपयोग करेंगे। जिस तरह से आपको यह करना है, वह मूल रूप से प्राथमिक कुंजी (PrimaryKeyRelatedField की तरह) to_internal_value में लेता है, लेकिन to_representation में एक धारावाहिक आउटपुट करता है।इस (untested) की तरह कुछ काम करना चाहिए

class PrimaryKeyNestedMixin(serializers.PrimaryKeyRelatedField, 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) 

आप इस, AccountSerializer अपने मामले में नेस्टेड serializer पर एक mixin के रूप में उपयोग करने की आवश्यकता होगी, और यह चाहिए आप के लिए क्या देख रहे हैं।

+0

और यह सभी धारावाहिकों के लिए मान्य है जो किसी अन्य धारावाहिक पर एक एफके हैं? यह एक सामान्य स्थिति के लिए एक अजीब दृष्टिकोण लगता है। यदि आपके पास