تعطيل إنشاء الكائنات المتداخلة في جانغو بقية الإطار
-
02-01-2020 - |
سؤال
مرحبا ،
هل يمكنك مساعدتي في كيفية تعطيل إنشاء الكائنات المتداخلة ?
لدي 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 لا تهدف إلى خلق الكائنات المتداخلة ، لذلك هذا هو السلوك غريبة جدا (أكثر تحديدا ، هذا هو التقدم في العمل, كما ذكر من قبل الخالق, توم كريستي).
ثم في مسلسل التمثيل الذي تريده يجب عليك اتباع بعض القواعد:
إنشاء بسيط مسلسل لكل نموذج (تماما مثل في أول مقتطف الشفرة)
إضافة FK العلاقة على EmployeeSerializer:(كن حذرا ، لهذا العمل ، يجب أن يكون لديك FK اسمه 'فريق') فريق = serializers.RelatedField()
- إضافة 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')
قليلا زائدة عن الحاجة ، ولكن ينبغي القيام بهذه المهمة.