2017-10-18 6 views
1

J'ai un modèle qui ressemble à ceci:Django Rest Framework - Remplacer sérialiseur créer la méthode pour le modèle avec le champ M2M autoréférentielle

class Profile(models.Model): 
    following = models.ManyToManyField('Profile', related_name='followed') 
    admin_notes = models.TextField() 

et un cadre de repos Django sérialiseur qui ressemble à ceci:

class ProfileSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Profile 
     fields = '__all__' 

Lors de la création d'un nouveau Profile Je veux interrompre l'enregistrement/créer pour définir admin_notes par programme. Je sais comment faire ceci à l'intérieur d'une vue basée sur la fonction, mais j'utilise les viewsets de DRF cette fois-ci et donc je veux le faire dans le sérialiseur. La relation auto-référentielle me donne cependant des problèmes.

J'ai essayé dans le ProfileSerializer:

def create(self, **validated_data): 
    p = Profile(**validated_data) 
    p.admin_notes = 'Test' 
    p.save() 

Ce, ainsi que d'essayer Profile.objects.create au lieu de simplement faire une nouvelle Profile par exemple dans la première ligne, a donné lieu à l'erreur suivante:

Exception Value: "<Profile>" needs to have a value for field "id" before this many-to-many relationship can be used. 

Essayer ceci:

def create(self, validated_data): 
    validated_data['admin_notes'] = 'Test' 
    return super(ProfileSerializer, self).create(**validated_data) 

Résultats dans cette erreur:

Exception Value: create() got an unexpected keyword argument 'following' 

Je comprends que Django crée des relations m2m dans un processus d'économie en deux étapes, de sorte que l'erreur est logique, mais encore me laisse perplexe quant à la façon dont je peux aller de l'avant. Comment puis-je définir la valeur de admin_notes dans le sérialiseur étant donné la façon dont mon modèle est configuré?

Répondre

1

Essayez ceci (en supposant que vous passez les IDs des instances de profil à votre champ m2m):

def create(self, validated_data): 

    # First, remove following from the validated_data dict... 
    following_data = validated_data.pop('following', None) 

    # Set the admin_notes custom value... 
    validated_data['admin_notes'] = 'Test' 

    # Create the object instance... 
    profile = Profile.objects.create(**validated_data) 

    # Finally, add your many-to-many relationships... 
    if following_data: 
     for data in following_data: 
      profile.followed.add(Profile.objects.get(**data)) 
    return profile