Hướng Dẫn Tham Gia Phát Triển Sentry - Sử Dụng Serializer Trong Django Rest Framework

Serializer dùng để chuyển đổi các mô hình python phức tạp thành định dạng json. Bộ tuần tự cũng có thể dùng để chuyển đổi dữ liệu json ngược lại thành mô hình Python sau khi xác thực dữ liệu đầu vào.

Trong Sentry, chúng ta có hai loại bộ tuần tự khác nhau: Django Rest Framework SerializerModel Serializer.

Django Rest Framework

Django Rest Framework serializer được sử dụng để xác thực và chuyển đổi dữ liệu đầu vào vào Sentry.

Ví dụ

Trong một serializer điển hình, các trường được chỉ định để chúng xác thực loại và định dạng dữ liệu theo thông số kỹ thuật của bạn. Nếu dữ liệu phù hợp để lưu vào model, Django Rest Framework serializer cũng có thể lưu thông tin vào cơ sở dữ liệu.

from rest_framework import serializers
from sentry.api.serializers.rest_framework import ValidationError

class SampleSerializer(serializers.Serializer):
    ten = serializers.CharField()
    tuoi = serializers.IntegerField(required=False)
    loai = serializers.CharField()

    def validate_loai(self, attrs, source):
        loai = attrs[source]
        if loai not in ['gau', 'tho', 'cho']:
            raise ValidationError('%s không phải là loại hợp lệ' % loai)
	return attrs

Kiểm tra trường

Trong ví dụ trên, serializer sẽ chấp nhận và xác thực json chứa ba trường: ten, tuoiloai. Trong đó tenloai phải là chuỗi, tươi phải là số nguyên. Theo mặc định, các trường là bắt buộc và nếu không cung cấp, serializer sẽ được đánh dấu là không hợp lệ. Lưu ý rằng trường số nguyên tuoi có cài đặt requiredFalse. Do đó có thể không bao gồm nó, serializer vẫn được coi là hợp lệ.

Xác thực tùy chỉnh

Đối với các giá trị cần xác thực tùy chỉnh (ngoài kiểm tra loại đơn giản),

def validate_<ten_bien>(self, attrs, source)

có thể tạo trong đó <ten_bien> được thay thế bằng tên biến chính xác của trường đã cho. Vì vậy, ví dụ, nếu tôi có một tên trường ten_loai, phương thức xác thực sẽ là validate_ten_loai, và nếu tôi có một trường tên ten_loai, phương thức xác thực sẽ là validate_ten_loai. Trong ví dụ được đưa ra ở trên, loại được kiểm tra và phải là một chuỗi cụ thể. Nếu một trường không khớp với những gì phương thức xác thực của bạn mong đợi, ValidationError sẽ được đưa ra.

Cách sử dụng

Trong endpoint, đây là cách sử dụng điển hình của Django Rest Framework Serializer

class SampleEndpoint(Endpoint):
    def post(self, request):
        serializer = SampleSerializer(request.DATA)
        if not serializer.is_valid():
            return Response(serializer.errors, status=400)

        result = serializer.object

        #Giả sử Sample là một mô hình với các trường tương tự 
        try:
            with transaction.atomic():
                Sample.objects.create(
                    ten=result['ten'],
                    tuoi=result.get('tuoi'),
                    loai=result['loai'],
                )
        except IntegrityError:
            return Response('Mẫu này đã tồn tại', status=409)

        return Response(serialize(result, request.user), status=201)

Xác thực dữ liệu

Serializer từ Django Rest Framework sẽ được sử dụng cho các phương thức cần xác thực dữ liệu đầu vào (tức là các phương thức putpost). Khi serializer được khởi tạo, bạn có thể gọi serializer.is_valid() để xác thực dữ liệu. serializer.errors sẽ đưa ra phản hồi cụ thể về lý do dữ liệu không hợp lệ.

Ví dụ, đầu vào được cung cấp

{
	'tuoi':5,
	'loai':'cho'
}

serializer sẽ trả về lỗi cho thấy trường tên bắt buộc không được cung cấp.

Lưu dữ liệu

Sau khi xác nhận dữ liệu hợp lệ, bạn có thể lưu dữ liệu bằng một trong hai cách. Ví dụ được đưa ra ở trên là phổ biến nhất trong sentry. Lấy serializer.object, đây chỉ là dữ liệu đã được xác thực (nếu serializer.is_valid() trả về False, thì sẽ là None) và sử dụng <ModelName>.objects.create lưu trực tiếp dữ liệu vào model.

Phương pháp khác sử dụng nhiều tính năng của Django Rest Framework hơn, ModelSerializer

from rest_framework import serializers
from sentry.api.serializers.rest_framework import ValidationError

class SampleSerializer(serializer.ModelSerializer):
    ten = serializers.CharField()
    tuoi = serializers.IntegerField(required=False)
    loai = serializers.CharField()

    class Meta:
        model = Sample
 
    def validate_loai(self, attrs, source):
        loai = attrs[source]
        if loai not in ['gau', 'tho', 'cho']:
            raise ValidationError('%s không phải là loại hợp lệ' % loai)
        return attrs

class SampleEndpoint(Endpoint):
    def post(self, request):
        serializer = SampleSerializer(request.DATA)
        if not serializer.is_valid():
            return Response(serializer.errors, status=400)

        sample = serializer.save()
        return Response(serialize(sample, request.user), status=201)

Model Serializer

Các Model Serializers của Sentry chỉ được sử dụng cho dữ liệu đầu ra. Một model serializer điển hình như sau:

@register(Sample)
class SampleModelSerializer(Serializer):
    def get_attrs(self, item_list, user):
        attrs = {}
        types = SampleTypes.objects.filter(
            type_name__in=[i.loai for i in item_list]
        )

        for item in item_list:
            attrs[item] = {}
            attrs[item]['loai'] = [t for t in types if t.ten == item.loai_ten]
	    return attrs

    def serialize(self, obj, attrs, user):
        return {
            'ten':obj.ten,
            'loai':attrs['loai'],
            'tuoi': obj.tuoi,
        }

Đăng ký Model Serializer

Decorator @register là cần thiết để

`return Response(serialize(sample, request.user), status=201)`

hoạt động. Trong trường hợp này, nó sẽ tìm kiếm ngầm model Sample phù hợp, dựa vào loại model của biến sample. Để kết nối model serializer với Model, bạn chỉ cần thực hiện

@register(<ModelName>)
class ModelSerializer(Serializer):
...

Phương thức get_attrs

Tại sao lại làm điều này khi Django Rest Framework đã có chức năng tương tự? get_attrs method là lý do. Nó cho phép bạn thực hiện các truy vấn hàng loạt thay vì nhiều truy vấn riêng lẻ. Trong ví dụ của chúng tôi, tôi có thể lọc các item mong muốn và sử dụng python để gán cho các item liên quan, thay vì gọi SampleTypes.objects.get(...) nhiều lần. Trong trường hợp của từ điển attr, keyitem chính nó. Và value là một từ điển chứa tên của thuộc tính cần thêm và giá trị của nó.

attrs[item] = {'ten_thuoc_tinh': gia_thuoc_tinh}

Phương thức Serialize

Cuối cùng, bạn trả về một từ điển chứa thông tin có thể tuần tự hóa json, thông tin này sẽ được trả về cùng với response.

Thêm

  • Giải pháp bảo mật dữ liệu doanh nghiệp Sentry - Hướng dẫn sử dụng Relay
  • Giải pháp bảo mật dữ liệu doanh nghiệp Sentry - Chế độ chạy Relay
  • Giải pháp bảo mật dữ liệu doanh nghiệp Sentry - Tùy chọn cấu hình Relay
  • Giải pháp bảo mật dữ liệu doanh nghiệp Sentry - Giám sát & Thu thập chỉ số Relay
  • Giải pháp bảo mật dữ liệu doanh nghiệp Sentry - Cấu hình dự án Relay
  • Hướng dẫn tham gia phát triển Sentry - Phát triển SDK (Giám hiệu năng: Tiến hóa API của Sentry SDK)

Thẻ: Django REST Framework Serializer sentry API python

Đăng vào ngày 5 tháng 7 lúc 04:25