因此,我想知道在django rest框架中是否可以用不同的序列化程序序列化每个外键对象。
我的意思是:
我的模特们就像
class KingdomModel(models.Model):
kingdom_name = models.CharField(max_length=32)
owner = models.OneToOneField(User, on_delete=models.CASCADE)
faction = models.CharField(max_length=10)
class CityModel(models.Model):
kingdom = models.ForeignKey(KingdomModel, on_delete=models.CASCADE, related_name="cities")
city_name = models.CharField(max_length=32)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
"""
... other fields aswell
"""
class ArmyModel(models.Model):
home_city = models.ForeignKey(CityModel, on_delete=models.CASCADE, null=True, related_name="own_troops")
current_city = models.ForeignKey(CityModel, on_delete=models.CASCADE, null=True, related_name="all_troops", blank=True)
status = models.CharField(max_length=32)
action_done_time = models.DateTimeField(default=None, null=True, blank=True)
target_city = models.ForeignKey(CityModel, on_delete=models.CASCADE, null=True, related_name="incoming_troops", default=None, blank=True)
# Shared troops
settlers = models.IntegerField(default=0)
# Gaul troops
pikemen = models.IntegerField(default=0)
swordmen = models.IntegerField(default=0)
riders = models.IntegerField(default=0)
# Roman troops
legionaries = models.IntegerField(default=0)
praetorian = models.IntegerField(default=0)我正试图以王国派系为基础,对军队进行系列化。在谈到own_troops时,它工作得很好,因为它们总是使用相同的序列化程序序列化,如下所示。
class CitySerializer(serializers.ModelSerializer):
own_troops = serializers.SerializerMethodField()
incoming_troops = serializers.SerializerMethodField()
def get_own_troops(self, city_obj):
if(KingdomModel.objects.get(owner=city_obj.owner).faction == "Gaul"):
return GaulTroopsSerializer(instance=city_obj.own_troops, context=self.context, many=True, required=False, read_only=False).data
elif(KingdomModel.objects.get(owner=city_obj.owner).faction == "Roman"):
return RomanTroopsSerializer(instance=city_obj.own_troops, context=self.context, many=True, required=False, read_only=False).dataclass RomanTroopsSerializer(serializers.ModelSerializer):
class Meta:
model = ArmyModel
fields = ['id', 'home_city', 'current_city', 'target_city', 'status', 'action_done_time', 'settlers', 'legionaries', 'praetorian']
class GaulTroopsSerializer(serializers.ModelSerializer):
class Meta:
model = ArmyModel
fields = ['id', 'home_city', 'current_city', 'target_city', 'status', 'action_done_time', 'settlers', 'pikemen', 'swordmen', 'riders']但是,如果我试图将相同的逻辑应用于序列化incoming_troops,它将始终使用第一个序列化程序序列化列表中的所有对象。这是我在基于关系中的数据用不同的序列化器序列化每个外键的毫无希望的尝试。
def get_incoming_troops(self, city_obj):
for data in GaulTroopsSerializer(instance=city_obj.incoming_troops, context=self.context, many=True, required=False, read_only=False).data:
print(data)
home_city_obj = CityModel.objects.get(id=data['home_city'])
if(KingdomModel.objects.get(owner=home_city_obj.owner).faction == "Gaul"):
return GaulTroopsSerializer(instance=city_obj.incoming_troops, context=self.context, many=True, required=False, read_only=False).data
else:
return RomanTroopsSerializer(instance=city_obj.incoming_troops, context=self.context, many=True, required=False, read_only=False).data
class Meta:
model = CityModel
fields = ['id', 'owner', 'city_name', 'x_coordinate', 'y_coordinate', 'last_updated', 'max_warehouse_capacity', 'max_grain_silo_capacity', 'wood_ammount', 'wheat_ammount', 'stone_ammount', 'iron_ammount', 'resource_fields', 'buildings','incoming_troops', 'own_troops', 'all_troops']
read_only_fields = ['id', 'max_warehouse_capacity', 'max_grain_silo_capacity']我知道我可以为所有不同派别的军队建立多个模型,但现在我只是想知道在django / drf中这是否可能?
发布于 2021-01-18 15:36:06
回答我自己的问题,因为我让它发挥作用,我做了以下几点:
首先,我刮了多个部队串行化器。而且只有一台军装连队,我在那里按派系交换战地。
这是我的ArmySerializer
class ArmySerializer(serializers.ModelSerializer):
class Meta:
model = ArmyModel
fields = ['id', 'home_city', 'current_city', 'target_city', 'status', 'action_done_time']
def to_representation(self, instance):
try:
del self.fields # Clear the cache
except AttributeError:
pass
if("faction" in self.context and len(self.context['faction']) > 0):
print(self.context['faction'])
self.fields['settlers'] = serializers.IntegerField()
if(self.context['faction'][0] == "Gaul"):
self.fields['pikemen'] = serializers.IntegerField()
self.fields['swordmen'] = serializers.IntegerField()
self.fields['riders'] = serializers.IntegerField()
elif(self.context['faction'][0] == "Roman"):
self.fields['legionaries'] = serializers.IntegerField()
self.fields['praetorian'] = serializers.IntegerField()
if(len(self.context['faction']) > 1):
self.context['faction'].pop(0)
return super().to_representation(instance)在CitySerializer中,我正在填充上下文“派系”列表,如下所示:
class CitySerializer(serializers.ModelSerializer):
own_troops = serializers.SerializerMethodField()
incoming_troops = serializers.SerializerMethodField()
def get_own_troops(self, instance):
if(KingdomModel.objects.get(owner=instance.owner).faction == "Gaul"):
self.context["faction"] = ["Gaul"]
return ArmySerializer(instance=instance.own_troops, context=self.context, many=True, required=False, read_only=False).data
elif(KingdomModel.objects.get(owner=instance.owner).faction == "Roman"):
self.context["faction"] = ["Roman"]
return ArmySerializer(instance=instance.own_troops, context=self.context, many=True, required=False, read_only=False).data
def get_incoming_troops(self, city_obj):
self.context['faction'] = []
for data in ArmySerializer(instance=city_obj.incoming_troops, context=self.context, many=True, required=False, read_only=False).data:
home_city = CityModel.objects.get(id=data['home_city'])
sender_faction = KingdomModel.objects.get(owner=home_city.owner).faction
if(sender_faction == "Gaul"):
self.context['faction'] += ["Gaul"]
else:
self.context['faction'] += ["Roman"]
return ArmySerializer(instance=city_obj.incoming_troops, context=self.context, many=True, required=False, read_only=False).data也应该说,这给创建有岗位要求的军队带来了一个新的问题。在to_representation方法中动态添加的字段在默认情况下不进行验证,因此它们不存在于validated_data中。也许有一种方法可以覆盖验证,但我现在只是从原始请求数据中提取了它们,它似乎运行得很好。
https://stackoverflow.com/questions/65681587
复制相似问题