Serializer is used to get complex Python models and convert them into json. The serializer can also be used to deserialize json back to the python model after validating the incoming data.
In Sentry, we have two different types of serializers: Django Rest Framework Serializer and Model Serializer.
Django Rest Framework
The Django Rest Framework serializer is used to handle input validation and transformation of data entering Sentry.
Example
In a typical serializer, fields are specified so that they validate the type and format of the data according to your specifications.
The Django Rest Framework serializer can also save the information to the database if the model is suitable for writing.
from rest_framework import serializers from sentry.api.serializers.rest_framework import ValidationError class ExampleSerializer(serializers.Serializer): name = serializers.CharField() age = serializers.IntegerField(required=False) type = serializers.CharField() def validate_type(self, attrs, source): type = attrs[source] if type not in ['bear', 'rabbit', 'puppy']: raise ValidationError('%s is not a valid type' % type) return attrs
Field check
In the example above,
The serializer will accept and validate a json with three fields: name, age, and type.
Where name and type must be strings,
age must be the recommended integer.
By default, fields are required, and if they are not provided, the serializer will mark them as invalid.
Note that the integer field age,required is set to False.
Therefore, it may not be included, and the serializer will still be considered valid.
Custom validation
For values that require custom validation (in addition to simple type checking),
def validate_<variable_name>(self, attrs, source)
You can create < variable_ Name > replace with the exact variable name of the given field.
So, for example, if I have a field name typename, the validation method name will be validate_typeName,
And if I have a name called type_name field, and the validation method name will be validate_type_name.
In the example given above, the type is checked and must be a string.
If a field does not match what your validation method expects, a ValidationError is thrown.
usage
In endpoint, this is the typical usage of Django Rest Framework Serializer
class ExampleEndpoint(Endpoint): def post(self, request): serializer = ExampleSerializer(request.DATA) if not serializer.is_valid(): return Response(serializer.errors, status=400) result = serializer.object #Assuming Example is a model with the same fields try: with transaction.atomic(): Example.objects.create( name=result['name'], age=result.get('age'), type=result['type'], ) except IntegrityError: return Response('This example already exists', status=409) return Response(serialize(result, request.user), status=201)
Validation data
The Serializer from Django Rest Framework will be used for the methods of incoming data that need to be verified (i.e. put and post methods).
Once the serializer is instantiated, you can call serializer is_ Validate () to validate the data.
serializer.errors will give specific feedback that the given data is invalid.
For example, given input
{ 'age':5, 'type':'puppy' }
The serializer will return an error indicating that the required field name was not provided.
Save data
After confirming that the data is valid, you can save the data in one of the following two ways.
The example given above is the most common in sentry.
Get serializer Object, which is only validated data (None if serializer.is_valid() returns False)
And use < modelname > objects. Create saves the data directly in the model
Another method uses more features of Django Rest Framework,
ModelSerializer
from rest_framework import serializers from sentry.api.serializers.rest_framework import ValidationError class ExampleSerializer(serializer.ModelSerializer): name = serializers.CharField() age = serializers.IntegerField(required=False) type = serializers.CharField() class Meta: model = Example def validate_type(self, attrs, source): type = attrs[source] if type not in ['bear', 'rabbit', 'puppy']: raise ValidationError('%s is not a valid type' % type) return attrs class ExampleEndpoint(Endpoint): def post(self, request): serializer = ExampleSerializer(request.DATA) if not serializer.is_valid(): return Response(serializer.errors, status=400) example = serializer.save() return Response(serialize(example, request.user), status=201)
Model Serializer
Sentry's Model Serializers For outgoing data only. A typical model serializer is as follows:
@register(Example) class ExampleSerializer(Serializer): def get_attrs(self, item_list, user): attrs = {} types = ExampleTypes.objects.filter( type_name__in=[i.type for i in item_list] ) for item in item_list: attrs[item] = {} attrs[item]['type'] = [t for t in types if t.name == item.type_name] return attrs def serialize(self, obj, attrs, user): return { 'name':obj.name, 'type':attrs['type'], 'age': obj.age, }
Register Model Serializer
The decorator @ register is required to
`return Response(serialize(example, request.user), status=201)`
works. In this case, it will search for the matching model Example in the background,
The model type of the given variable example.
To match the model serializer to the Model, you simply execute
@register(<ModelName>) class ModelSerializer(Serializer): ...
get_attrs method
Why do you do this when the Django Rest Framework has similar functionality?
get_ The attrs method is the reason. It allows you to perform batch queries instead of multiple queries.
In our example, I can filter the items I want and assign them to related items using python,
Instead of calling exampletypes objects. get(...) Multiple item s.
In the case of attr dictionary, the key is the item itself.
And value is a dictionary that contains the name of the attribute to be added and its value.
attrs[item] = {'attribute_name': attribute}
Serialize method
Finally, you return a dictionary with json serializable information that will be returned with the response.
more
- Sentry enterprise data security solution - getting started with Relay
- Sentry enterprise data security solution - Relay operation mode
- Sentry enterprise data security solution - Relay configuration options
- Sentry enterprise data security solution - Relay Monitoring & indicator collection
- Sentry enterprise data security solution - Relay project configuration
- Sentry developer contribution Guide - SDK development (performance monitoring: Sentry SDK API evolution)