본문 바로가기

TIL

TIL 080323

Q: Serializer에서 Custom Validation을 하는 이유는 무엇입니까?

A: 

Validation in REST framework

DRF에서 serializer의 벨리데이션은 Django의 ModelForm 클래스에서 벨리데이션이 작동하는 방식과 약간 다르게 처리됩니다.

ModelForm을 사용하면 벨리데이션 폼에서 부분적(partial)으로 실행되고 모델 인스턴스에서 부분적으로 수행됩니다. DRF를 사용하면 벨리데이션이 전적으로 serializer클래스에서 수행됩니다. 이는 다음과 같은 이유로 유리합니다.

  • 문제를 적절하게 분리하여 코드 동작을 보다 명확하게 만듭니다.
  • shortcut ModelSerializer 클래스 사용과 명시적 Serializer 클래스 사용 사이를 쉽게 전환할 수 있습니다. ModelSerialzier에 사용되는 모든 벨리데이션은 복제하기 쉽습니다.
  • Serializer 인스턴스의 repr을 인쇄하면 적용되는 벨리데이션 규칙이 정확히 표시됩니다. 모델 인스턴스에서 추가로 숨겨진 벨리데이션 동작이 호출되지 않습니다.

https://hyun-am-coding.tistory.com/entry/12-Validators

 

12-Validators

Validators DRF에서 유효성 검사를 처리하는 대부분의 경우 단순히 기본 필드 유효성 검사에 의존하거나 serialzier 또는 필드 클래스에 대한 명시적 유효성 검사 메서드를 작성합니다. 그러나 때로는

hyun-am-coding.tistory.com

https://www.django-rest-framework.org/api-guide/validators/

 

Validators - Django REST framework

 

www.django-rest-framework.org

 

 

 

 

Q: Serializer에서 create, update 함수는 어떤 기능을 수행합니까?

A: 

  • create = 유효성 검사를 통과한 데이터들을 바탕으로 새로운 DB인스턴스를 생성하고 반환합니다
  • update = 유효성 검사를 통과한 데이터들을 바탕으로 기존의 DB 인스턴스를 수정하고 반환합니다

Saving instances

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:

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

    def create(self, validated_data):
        return Comment(**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)
        return instance

If your object instances correspond to Django models you'll also want to ensure that these methods save the object to the database. For example, if Comment was a Django model, the methods might look like this:

    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

Now when deserializing data, we can call .save() to return an object instance, based on the validated data.

comment = serializer.save()

Calling .save() will either create a new instance, or update an existing instance, depending on if an existing instance was passed when instantiating the serializer class:

# .save() will create a new instance.
serializer = CommentSerializer(data=data)

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

Both the .create() and .update() methods are optional. You can implement either none, one, or both of them, depending on the use-case for your serializer class.

Passing additional attributes to .save()

Sometimes you'll want your view code to be able to inject additional data at the point of saving the instance. This additional data might include information like the current user, the current time, or anything else that is not part of the request data.

You can do so by including additional keyword arguments when calling .save(). For example:

serializer.save(owner=request.user)

Any additional keyword arguments will be included in the validated_data argument when .create() or .update() are called.

Overriding .save() directly.

In some cases the .create() and .update() method names may not be meaningful. For example, in a contact form we may not be creating new instances, but instead sending an email or other message.

In these cases you might instead choose to override .save() directly, as being more readable and meaningful.

For example:

class ContactForm(serializers.Serializer):
    email = serializers.EmailField()
    message = serializers.CharField()

    def save(self):
        email = self.validated_data['email']
        message = self.validated_data['message']
        send_email(from=email, message=message)

Note that in the case above we're now having to access the serializer .validated_data property directly.

 

https://www.django-rest-framework.org/api-guide/serializers/

 

Serializers - Django REST framework

 

www.django-rest-framework.org

 

 

 

+ GIL, numpy

https://superfastpython.com/numpy-vs-gil/

 

NumPy vs the Global Interpreter Lock (GIL)

You can parallelize numpy tasks with threads in Python because most numpy functions release the global interpreter lock or GIL. In this tutorial, you will discover that most numpy array functions w…

superfastpython.com

 

'TIL' 카테고리의 다른 글

TIL 080723  (0) 2023.08.07
TIL 080423  (0) 2023.08.04
TIL 080223  (0) 2023.08.02
TIL 080123  (0) 2023.08.01
TIL 073123  (0) 2023.07.31