Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Django REST framework - DjangoConG 2015

Django REST framework - DjangoConG 2015

A few non trivial use cases with Django REST framework

xordoquy

May 09, 2015
Tweet

More Decks by xordoquy

Other Decks in Programming

Transcript

  1. Ajouter des données à la création # ViewSet: def perform_create(self,

    serializer): serializer.save(owner=request.user) # Serializer: def create(self, validated_data): # process validated_data['owner'] return Task.objects.create(**validated_data)
  2. from rest_framework import routers router = routers.SimpleRouter() router.register(r'task', TaskViewSet, base_name='task')

    urlpatterns = router.urls Sans modèle ? class TaskViewSet(viewsets.ViewSet): def list(self, request): # Recuperation des taches return tasks def retrieve(self, request, pk=None): # Récupération de la tache return task
  3. serializers et contextes • Serializer et Fields ont parfois besoin

    d’un contexte: • URL complète pour hyperlink • Utile pour « to_representation »
  4. class PostSerializer(serializers.ModelSerializer): fav = serializers.SerializerMethodField('liked') def liked(self, obj): request =

    self.context.get('request', None) if request is not None: return Favorite.objects.filter( user=request.user, post_id=obj.id).exists() return "error" class Meta: model = Post fields = ('fav', 'name') serializers et contextes
  5. owner = serializers.HiddenField( default=CurrentUserDefault() ) class CurrentUserDefault(object): def set_context(self, serializer_field):

    self.user = serializer_field.context['request'].user def __call__(self): return self.user def __repr__(self): return unicode_to_repr('%s()' % self.__class__.__name__) serializers et contextes
  6. Plusieurs serializers class MultiSerializerViewSetMixin(object): def get_serializer_class(self): """ Thanks gonz: http://stackoverflow.com/a/22922156/11440

    """ try: return self.serializer_action_classes[self.action] except (KeyError, AttributeError): return super( MultiSerializerViewSetMixin, self).get_serializer_class()
  7. class CreateUserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('email',

    'username', 'password') extra_kwargs = {'password': {'write_only': True}} Personnalisation d’un champ
  8. Représentations imbriquées { "name": "Estimation #45", "client": { "name": "Client

    idéal", "phone": "0101010101" }, "items": [{ "name": "Specification", "quantity": 2, }, { "name": "Tests", "quantity": 10, }] } class Estimate(models.Model): name = models.CharField(max_length=64) client = models.ForeignKey(User) items = models.ManyToManyField(Item)
  9. Serializer class EstimateSerializer(serializers.ModelSerializer): client = ClientSerializer() items = ItemsSerializer() class

    Meta: model = Estimate fields = ('name', 'client', 'items') def create(self, validated_data): client_data = validated_data.pop('client') items_data = validated_data.pop('items') client = Client.objects.get_or_create(**client_data) est = Est.objects.create(client=client, **validated_data) for item in items_data: Item.objects.create(estimate=est, **items_data) return est
  10. Serializer class EstimateSerializer(serializers.ModelSerializer): client = ClientSerializer() items = ItemsSerializer() class

    Meta: model = Estimate fields = ('name', 'client', 'items') def create(self, validated_data): client_data = validated_data.pop('client') items_data = validated_data.pop('items') client = Client.objects.get_or_create(**client_data) est = Est.objects.create(client=client, **validated_data) for item in items_data: Item.objects.create(estimate=est, **items_data) return est
  11. Serializer class EstimateSerializer(serializers.ModelSerializer): client = ClientSerializer() items = ItemsSerializer() class

    Meta: model = Estimate fields = ('name', 'client', 'items') def create(self, validated_data): client_data = validated_data.pop('client') items_data = validated_data.pop('items') client = Client.objects.get_or_create(**client_data) est = Est.objects.create(client=client, **validated_data) for item in items_data: Item.objects.create(estimate=est, **items_data) return est
  12. Serializer class EstimateSerializer(serializers.ModelSerializer): client = ClientSerializer() items = ItemsSerializer() class

    Meta: model = Estimate fields = ('name', 'client', 'items') def create(self, validated_data): client_data = validated_data.pop('client') items_data = validated_data.pop('items') client = Client.objects.get_or_create(**client_data) est = Est.objects.create(client=client, **validated_data) for item in items_data: Item.objects.create(estimate=est, **items_data) return est
  13. Serializer class EstimateSerializer(serializers.ModelSerializer): client = ClientSerializer() items = ItemsSerializer() class

    Meta: model = Estimate fields = ('name', 'client', 'items') def create(self, validated_data): client_data = validated_data.pop('client') items_data = validated_data.pop('items') client = Client.objects.get_or_create(**client_data) est = Est.objects.create(client=client, **validated_data) for item in items_data: Item.objects.create(estimate=est, **items_data) return est
  14. Serializer class EstimateSerializer(serializers.ModelSerializer): client = ClientSerializer() items = ItemsSerializer() class

    Meta: model = Estimate fields = ('name', 'client', 'items') def create(self, validated_data): client_data = validated_data.pop('client') items_data = validated_data.pop('items') client = Client.objects.get_or_create(**client_data) est = Est.objects.create(client=client, **validated_data) for item in items_data: Item.objects.create(estimate=est, **items_data) return user
  15. { "task": "Troller Jean Michel" } { "task": "Troller Jean

    Michel", "owner": None } { "task": "Troller Jean Michel", "owner": "" } { "task": "Troller Jean Michel", "owner": "Mat" }
  16. Validation des données: 2 écoles • Tout dans le serializer

    • Deux passes: • Validation avec l’extérieur • Validation des règles du modèle
  17. Validation serializer print(repr(t)) Task(): id = IntegerField(label='ID', read_only=True) name =

    CharField(max_length=64) owner = SlugRelatedField( queryset=[<User: admin>, <User: toto>], slug_field='username') categories = SlugRelatedField(many=True, queryset=[<Category: pouet>, <Category: Django>], slug_field='name') done = BooleanField(required=False)