web-dev-qa-db-fra.com

Champ supplémentaire lors de la sérialisation Django rest framework

Je suis un débutant au cadre de repos Django et j'ai créé un exemple de modèle Employee.

Mon models.py:

class Employees(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

Mon serializers.py:

class EmployeeSerializer(serializers.Serializer):
    class Meta:
        model = Employees
        fields = ('first_name','last_name')

Cela fonctionne bien mais je veux un champ supplémentaire full_name, qui sera first_name + last_name.

Comment définir ce nouveau champ full_name dans mon serializers.py?

42
user1050619

Je vois deux façons ici (je préfère la première puisque vous pouvez la réutiliser dans d'autres parties de l'application):

ajoutez une propriété calculée à votre modèle et ajoutez-la à votre sérialiseur en utilisant n champ en lecture seule avec source =

# models.py
class Employees(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    @property
    def full_name(self):
        return self.first_name + self.last_name

#serializes.py
class EmployeeSerializer(serializers.ModelSerializer):
    full_name = serializers.Field(source='full_name')

    class Meta:
        model = Employees
        fields = ('first_name','last_name', 'full_name')

en utilisant SerializerMethodField (votre modèle est inchangé)

class EmployeeSerializer(serializers.ModelSerializer):
    full_name = serializers.SerializerMethodField('get_full_name')

    def get_full_name(self, obj):
        return obj.first_name + obj.last_name

    class Meta:
        model = Employees
        fields = ('first_name','last_name', 'full_name')
72
Denis Cornehl

À condition que Employee soit un utilisateur de connexion, la plupart d'entre nous utiliseront Django.auth.User, Je vais partager comment Employee peut être implémenté comme un autre Profile (extension de Django User). Également avec l'ajout de full_name.read_only, first_name.write_only, et last_name.write_only

# models.py
class Employee(models.Model):
    """User Profile Model"""
    user = models.OneToOneField('auth.User')

# serializers.py
class EmployeeSerializer(serializers.HyperlinkedModelSerializer):
    username = serializers.CharField(source='user.username')
    email = serializers.EmailField(source='user.email')

    first_name = serializers.CharField(
            source='user.first_name', write_only=True)
    last_name = serializers.CharField(
            source='user.last_name', write_only=True)
    name = serializers.CharField(
            source='user.get_full_name', read_only=True)


    class Meta:
        model = Employee
        fields = (
            'url', 'username', 'email',
            'first_name', 'last_name', 'name')
        depth = 1
4
Yeo

SerializerMethodField fonctionne très bien, et nous pouvons également stocker des données dans un objet sérialiseur et laisser la méthode get_field_name Utiliser ça.

Exemple:

class MySerializer(serializers.ModelSerializer):
    statistic = serializers.SerializerMethodField()

    def __init__(self, instance=None, data=serializers.empty, statistic=None, **kwargs):
        super(MySerializer, self).__init__(instance=instance, data=data, **kwargs)
        self.statistic = statistic

    def get_statistic(self, obj):
        if self.statistic is None:
            return serializers.empty
        return self.statistic.get(obj.id, {})
3
Craynic Cai