मैं Django रेस्ट फ्रेमवर्क का उपयोग करके संबंधित मॉडल फ़ील्ड कैसे शामिल करूं?


154

मान लीजिए कि हमारे पास निम्नलिखित मॉडल हैं:

class Classroom(models.Model):
    room_number = [....]

class Teacher(models.Model):
    name = [...]
    tenure = [...]
    classroom = models.ForeignKey(Classroom)

मान लीजिए कि इसके बजाय ManyRelatedPrimaryKeyField फ़ंक्शन के अनुसार परिणाम प्राप्त होता है:

{
    "room_number": "42", 
    "teachers": [
        27, 
        24, 
        7
    ]
},

क्या यह कुछ ऐसा है जिसमें पूर्ण संबंधित मॉडल प्रतिनिधित्व शामिल है:

{
    "room_number": "42", 
    "teachers": [
        {
           'id':'27,
           'name':'John',
           'tenure':True
        }, 
        {
           'id':'24,
           'name':'Sally',
           'tenure':False
        }, 
    ]
},

क्या यह संभव है? यदि हां, तो कैसे? और क्या यह एक बुरा विचार है?

जवाबों:


242

सबसे सरल तरीका गहराई तर्क का उपयोग करना है

class ClassroomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Classroom
        depth = 1

हालाँकि, इसमें केवल आगे के रिश्तों के लिए रिश्ते शामिल होंगे, जो कि इस मामले में आपकी ज़रूरत नहीं है, क्योंकि शिक्षक क्षेत्र एक रिवर्स संबंध है।

यदि आपको अधिक जटिल आवश्यकताएं मिली हैं (उदाहरण के लिए, रिवर्स रिलेशनशिप शामिल हैं, तो कुछ फ़ील्ड्स को घोंसला दें, लेकिन दूसरों को नहीं, या केवल फ़ील्ड के एक विशिष्ट सबसेट को घोंसले में न डालें ) आप सीरियसलाइज़र को घोंसला बना सकते हैं , जैसे ...

class TeacherSerializer(serializers.ModelSerializer):
    class Meta:
        model = Teacher
        fields = ('id', 'name', 'tenure')

class ClassroomSerializer(serializers.ModelSerializer):
    teachers = TeacherSerializer(source='teacher_set')

    class Meta:
        model = Classroom

ध्यान दें कि हम क्षेत्र के स्रोत के रूप में उपयोग करने के लिए विशेषता निर्दिष्ट करने के लिए क्रमिक क्षेत्र पर स्रोत तर्क का उपयोग करते हैं। हम यह sourceसुनिश्चित करने के बजाय कि आपके मॉडल पर संबंधित_नाम विकल्प teachersका उपयोग करके विशेषता मौजूद है , तर्क को छोड़ सकते हैं ।Teacherclassroom = models.ForeignKey(Classroom, related_name='teachers')

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


जब मैंने पहला समाधान आज़माया, तो मुझे शिक्षक नहीं मिले, हालाँकि मुझे कक्षा के माता-पिता के उदाहरण मिलते थे (जो कि यह उदाहरण नहीं दिखाता है)। दूसरे समाधान में मुझे एक त्रुटि मिली - "'क्लासरूम' ऑब्जेक्ट में कोई विशेषता 'शिक्षक' नहीं है"। क्या मैं कुछ भूल रहा हूँ?
चेज़

1
@Chaz depthइस मामले में आपको क्या करना चाहिए, यह समझाने के लिए उत्तर का अद्यतन करना, और उस अपवाद को स्पष्ट करना, जिसे आप देख रहे हैं और इससे कैसे निपटें।
टॉम क्रिस्टी

1
मैं एक बेवकूफ हूँ और गलत सर्वर मार रहा था। यह निश्चित रूप से कई रिश्तों में कई काम करता है।
येलोट्टीटेलॉट

15
घोंसले के शिकार सीरियल भयानक है! मुझे यह करना था और डीआरएफ 3.1.0 का उपयोग कर रहा था। मैं शामिल करने के लिए किया था many=Trueइसलिए की तरह ...TeacherSerializer(source='teacher_set', many=True)। अन्यथा मुझे निम्नलिखित त्रुटि हो रही थी:The serializer field might be named incorrectly and not match any attribute or key on the 'RelatedManager' instance. Original exception text was: 'RelatedManager' object has no attribute 'type'.
कार्तिक रघुपति

2
फॉरेनके के रिवर्स साइड को ..._setडिफ़ॉल्ट रूप से नाम दिया जाएगा । अधिक जानकारी के लिए Django डॉक्स देखें: docs.djangoproject.com/en/1.10/ref/models/relations/…
टॉम क्रिस्टी

36

शुक्रिया @TomChristie !!! आपने मेरी बहुत मदद की! मैं अपडेट करना चाहूंगा कि थोड़ा (एक गलती के कारण मैं भाग गया)

class TeacherSerializer(serializers.ModelSerializer):
    class Meta:
        model = Teacher
        fields = ('id', 'name', 'tenure')

class ClassroomSerializer(serializers.ModelSerializer):
    teachers = TeacherSerializer(source='teacher_set', many=True)

    class Meta:
        model = Classroom
        field = ("teachers",)

2

इसे ड्रफ-फ्लेक्स-फ़ील्ड्स नामक एक बहुत ही आसान डंडी डिंगैंगो का उपयोग करके भी पूरा किया जा सकता है । हम इसका उपयोग करते हैं और यह बहुत बढ़िया है। आप बस इसे स्थापित करें pip install drf-flex-fields, इसे अपने धारावाहिक के माध्यम से जोड़ें, expandable_fieldsबिंगो और (उदाहरण के नीचे)। यह आपको डॉट नोटेशन का उपयोग करके भी गहरे नेस्टेड रिश्तों को निर्दिष्ट करने की अनुमति देता है।

from rest_flex_fields import FlexFieldsModelSerializer

class ClassroomSerializer(FlexFieldsModelSerializer):
    class Meta:
        model = Model
        fields = ("teacher_set",)
        expandable_fields = {"teacher_set": (TeacherSerializer, {"source": "teacher_set"})}

फिर आप ?expand=teacher_setअपने URL में जोड़ते हैं और यह एक विस्तारित प्रतिक्रिया देता है। आशा है कि यह किसी दिन मदद करता है। चीयर्स!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.