简体   繁体   English

混合Django Rest Framework中序列化器之间的公共字段

[英]Mixin common fields between serializers in Django Rest Framework

I have this: 我有这个:

class GenericCharacterFieldMixin():
    attributes = serializers.SerializerMethodField('character_attribute')
    skills = serializers.SerializerMethodField('character_skill')

    def character_attribute(self, obj):
        character_attribute_fields = {}
        character_attribute_fields['mental'] = {str(trait_item.get()): trait_item.get().current_value
                                                for trait_item in obj.mental_attributes}
        character_attribute_fields['physical'] = {str(trait_item.get()): trait_item.get().current_value
                                                  for trait_item in obj.physical_attributes}
        character_attribute_fields['social'] = {str(trait_item.get()): trait_item.get().current_value
                                                for trait_item in obj.social_attributes}
        return character_attribute_fields

    def character_skill(self, obj):
        character_skill_fields = {}
        character_skill_fields['mental'] = {str(trait_item.get()): trait_item.get().current_value
                                            for trait_item in obj.mental_skills}
        character_skill_fields['physical'] = {str(trait_item.get()): trait_item.get().current_value
                                              for trait_item in obj.physical_skills}
        character_skill_fields['social'] = {str(trait_item.get()): trait_item.get().current_value
                                            for trait_item in obj.social_skills}
        return character_skill_fields


class MageSerializer(GenericCharacterFieldMixin, serializers.ModelSerializer):
    player = serializers.ReadOnlyField(source='player.username')
    arcana = serializers.SerializerMethodField()

    def get_arcana(self, obj):
        if obj:
            return {str(arcana): arcana.current_value for arcana in obj.linked_arcana.all()}

    class Meta:
        model = Mage
        fields = ('id', 'player', 'name', 'sub_race', 'faction', 'is_published',
                  'power_level', 'energy_trait', 'virtue', 'vice', 'morality', 'size',
                  'arcana', 'attributes', 'skills')
        depth = 1

GenericCharacterFieldMixin is a Mixin of Fields for Characters, that are Generic, ie common to all types of characters. GenericCharacterFieldMixin是字符字段的混合,它是通用的,即对所有类型的字符都是通用的。

I'd like my Mage Serializer to have these 'mixed in' rather than c/p then between all types of character (Mage is a type of character) hopefully this will increase DRYness in my webapp. 我希望我的Mage Serializer能够在所有类型的角色之间使用'混合'而不是c / p(Mage是一种角色),希望这会增加我的webapp中的DRY。

The issue is on the model I have this: 问题在于我有这个模型:

class NWODCharacter(models.Model):

    class Meta:
        abstract = True
        ordering = ['updated_date', 'created_date']

    name = models.CharField(max_length=200)
    player = models.ForeignKey('auth.User', related_name="%(class)s_by_user")
    ....

    def save(self, *args, **kwargs):
        ...

    attributes = GenericRelation('CharacterAttributeLink')
    skills = GenericRelation('CharacterSkillLink')

Which means I get this error: 这意味着我收到此错误:

TypeError at /characters/api/mages
<django.contrib.contenttypes.fields.create_generic_related_manager.<locals>.GenericRelatedObjectManager object at 0x00000000051CBD30> is not JSON serializable

Django Rest Framework thinks I want to serialize my generic relationship. Django Rest Framework认为我想序列化我的通用关系。

If I rename the fields in the model ( s/attributes/foos/g , s/skills/bars/g ) then I get a different (less clear?) error : 如果我重命名模型中的字段( s/attributes/foos/gs/skills/bars/g ),那么我得到一个不同的(不太清楚?)错误:

ImproperlyConfigured at /characters/api/mages
Field name `attributes` is not valid for model `ModelBase`.

How do I pull those methods and fields into a mixin, without confusing DRF? 如何在不混淆DRF的情况下将这些方法和字段拖入混合中?

Solution is simple as changing 解决方案很简单

class GenericCharacterFieldMixin():

to

class GenericCharacterFieldMixin(serializers.Serializer):

i had same issue and my google search brought me here. 我有同样的问题,我的谷歌搜索把我带到了这里。 i managed to solve it. 我设法解决了它。 since you are including attributes and skill fields in serialiser, you need to provide serialisation method for it. 由于您在序列化程序中包含属性和技能字段,因此需要为其提供序列化方法。

this worked for me 这对我有用

class MageSerializer(GenericCharacterFieldMixin, serializers.ModelSerializer):
    player = serializers.ReadOnlyField(source='player.username')
    arcana = serializers.SerializerMethodField()


    attributes = serializers.PrimaryKeyRelatedField(many=True, 
                                read_only= True)
    skills = serializers.PrimaryKeyRelatedField(many=True, 
                                read_only= True)


    def get_arcana(self, obj):
      if obj:
        return {str(arcana): arcana.current_value for arcana in obj.linked_arcana.all()}

    class Meta:
        model = Mage
        fields = ('id', 'player', 'name', 'sub_race', 'faction', 'is_published',
                  'power_level', 'energy_trait', 'virtue', 'vice', 'morality', 'size',
                  'arcana', 'attributes', 'skills')
        depth = 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM