TIL

Web Dev Bootcamp Day TIL Day-47(DRF Serializers)

frannyk 2022. 6. 18. 20:47
  • Why use Serializers?
    • Serializers allow us to easily control the output of our API responses
    • We can convert complex data types such as querysets and model instances to JSON types
    • Serializers provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data
    • Serializers also help us place validation logic into reusable components
  • For Django, the ModelSeralizers class is generally used to deal with converting querysets and model instances
  • ModelSerializer Meta Class 
    • Settings file within serializer
    • Declares the model/table and fields that will be used in the serializer
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
   class Meta:
        model = User
        # if we wish to use all fields, set fields = "__all__"
        fields = ["username", "password", "fullname", "email"]
  • Nesting serializers
    • To output multi-level JSON types, we can nest serializers
    • This allows us to use fields from tables that have foreign key relationships to our current table
  • Serializing multiple objects
    • To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer.
    • You can then pass a queryset or list of objects to be serialized.
from rest_framework import serializers
from User.models import *

class DishSerializer(serializers.ModelSerializer):
    # we can create a reverse lookup function inside a Serializer
    same_dish_users = serializers.SerializerMethodField()
    def get_same_dish_users(self, obj):
        return [up.user.realname for up in obj.userprofile_set.all()]

    class Meta:
        model = Dish
        fields = ["name", "same_dish_users"]

class UserProfileSerializer(serializers.ModelSerializer):        
    # note that Dish and UserProfile have a many-to-many relationship
    # if the input data is a QuerySet, we will need to add the parameter (many=True)
    favorite_dish = DishSerializer(many=True)
    class Meta:
        model = UserProfile
        fields = ["TMI", "age", "favorite_dish"]

class UserSerializer(serializers.ModelSerializer):
    userprofile = UserProfileSerializer()
    class Meta:
        model = CustomUser
        fields = ["username", "realname", "email", "join_date", "userprofile"]

 

  • If we want to be able to return complete object instances based on the validated data we need to implement one or both of the .create() and .update() methods.
    • For example, if Comment was a Django model, the methods might look like this:
class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = "__all__"
	
    # validated data is data that corresponds to the fields in our table
    # notices that validated data is taken as kwargs
    def create(self, validated_data):
        return Comment.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.email = validated_data.get('email', instance.email)
        instance.content = validated_data.get('content', instance.content)
        instance.created = validated_data.get('created', instance.created)
        instance.save()
        return instance
        
# .save() will create a new instance.
serializer = CommentSerializer(data=data)

# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)
    
comment = Commetserializer.save()