سؤال

مرحبا ،

هل يمكنك مساعدتي في كيفية تعطيل إنشاء الكائنات المتداخلة ?

لدي serializers مثل هذا:
(الموظف ForeignKey إلى فريق)

class TeamSerializer(serializers.ModelSerializer):
    class Meta:
        model = Team
        fields = ('id', 'name')
class EmployeeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Employee
        fields = ('id', 'name', 'surname', 'team')
        depth = 1

أو بدلا من ذلك يمكن أن تكون:

class EmployeeSerializer(serializers.ModelSerializer):
    team = TeamSerializer()
    class Meta:
        model = Employee
        fields = ('id', 'name', 'surname', 'team')

عندما أنشر سلمان (إنشاء الموظف)

{
    name: "name",
    surname: "surname",
    team: {
           id: 1,
           name: "Web Team"
          }
}

كائن الموظف يخلق ولكن أيضا كائن فريق...هل هناك أي طريقة لتعطيل إنشاء فريق كائن جنبا إلى جنب مع الموظف ؟ أريد فقط أن إنشاء الموظف و مجموعة مختارة من فريق (لcurently في قاعدة البيانات) إلى الموظف

وعن على (قائمة) وأود أن تكون قادرة على استرداد البيانات مثل:

{
 name: "name",
 surname: "surname",
 team: {
    id: 1,
    name: "Web Team"
 }

ليس هكذا

{
 name: "name",
 surname: "surname",
 team: 1
}

هل هناك أي طريقة في جانغو بقية إطار (أيضا iam باستخدام الزاوي)
تحياتي

التحديث

حاليا serializers:

class TeamSerializer(serializers.ModelSerializer):
    class Meta:
        model = Team

class EmployeeSerializer(serializers.ModelSerializer):
    team = TeamSerializer()

    class Meta:
        model = Employee

أنا غير قادر على استخدام serializers.RelatedField() لأنه عاد فقط unicode أحتاج 'id' و 'اسم' (أعتقد)

هذا هو بلدي آخر سلمان:( Restangular.كل('موظف').بعد(البيانات) )

data: {
        name: "emp1",
        photo: "",
        skype: "",
        surname: "qweqwe",
        team: {
              id: 1,
              name: "Web",
        }
}

و DRF عاد سلمان:

employee: {
    id: 2,
    name: "emp1",
    photo: "",
    skype: "",
    surname: "qweqwe",
    team: {
        id:3, <-- NEW ID!
        name: "Web"
    }   
}

لذا نعم, أنا متأكد من أن الفريق الجديد الكائنات التي تم إنشاؤها.ماذا الآن؟:)

هل كانت مفيدة؟

المحلول 3

حل المشكلة:

class ReadEmployeeSerializer(serializers.ModelSerializer):
    team = TeamSerializer()

    class Meta:
        model = Employee
        fields = ('id', 'name', 'surname', 'team',)


class WriteEmployeeSerializer(serializers.ModelSerializer):

    def from_native(self, data, files):
        data['team'] = data['team']['id']
        return serializers.ModelSerializer.from_native(self, data, files)

    def to_native(self, obj):
        return ReadEmployeeSerializer(obj).data

    class Meta:
        model = Employee
        fields = ('id', 'name', 'surname', 'team',)

الوظيفة/وضع طريقة استخدام المفتاح الأساسي (WriteEmployeeSerializer) - قبل محل ديكت أن المفتاح الأساسي

على طريقة استخدام كائن كامل (ReadEmployeeSerializer)

نصائح أخرى

وجدت أن ModelSerializer.to_native() و ModelSerializer.from_native() لا توجد في أحدث نسخة من DRF.خطرت التالية المستمدة من الحل المقبول:

class PlayerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Player
        fields = ('id', 'name', 'team')

    def to_internal_value(self, data):
        # If team is not a dict, such as when submitting via the Browseable UI, this would fail.
        try:
            data['team'] = data['team']['id']
        except TypeError:
            pass
        return super(PlayerSerializer, self).to_internal_value(data)

    def to_representation(self, instance):
        return ReadPlayerSerializer(instance).data


class ReadPlayerSerializer(serializers.ModelSerializer):
    team = TeamSerializer()

    class Meta(PlayerSerializer.Meta):
        pass

على نحو فعال ، يبدو أن from_native الآن to_representation, ، to_native لا to_internal_value

حسنا, أولا وقبل كل شيء ، هل أنت متأكد أن المتداخلة كائن خلقت ؟ لأن DRF لا تهدف إلى خلق الكائنات المتداخلة ، لذلك هذا هو السلوك غريبة جدا (أكثر تحديدا ، هذا هو التقدم في العمل, كما ذكر من قبل الخالق, توم كريستي).

ثم في مسلسل التمثيل الذي تريده يجب عليك اتباع بعض القواعد:

  1. إنشاء بسيط مسلسل لكل نموذج (تماما مثل في أول مقتطف الشفرة)

  2. إضافة FK العلاقة على EmployeeSerializer:(كن حذرا ، لهذا العمل ، يجب أن يكون لديك FK اسمه 'فريق') فريق = serializers.RelatedField()

  3. إضافة ManyToOne العلاقة على TeamSerializer:(هذا يحتاج فقط إذا كنت تريد أيضا أن يكون جميع الموظفين الخاص بك عندما تحصل فريق الكائن ؛ إن لم يكن, يمكنك تخطي هذا الجزء) الموظفين = EmployeeSerializer(مطلوب=False العديد من=صحيح)

كما يجب إزالة عمق سمة من مسلسل أنه هو الذي يسطح التسلسل الخاص بك (أو يمكنك فقط تعيين إلى 2).ويساعد هذا الأمل.

التحديث

عرض متعددة serializers:

def get_serializer_class(self):
    if self.request.method == 'GET':
        return ReadEmployeeSerializer
    elif self.request.method == 'POST':
        return WriteEmployeeSerializer
    else:
        return DefaultSerializer

class WriteEmployeeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Employee
        fields = ('id', 'name', 'surname', 'team')

class ReadEmployeeSerializer(serializers.ModelSerializer):
    team = TeamSerializer()
    class Meta:
        model = Employee
        fields = ('id', 'name', 'surname', 'team')

قليلا زائدة عن الحاجة ، ولكن ينبغي القيام بهذه المهمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top