In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.
SlugRelatedField may be used to represent the target of the relationship using a field on the target. For example, the following serializer: class AlbumSerializer(serializers. ModelSerializer): tracks = serializers.
Creating and Using Serializers To create a basic serializer one needs to import serializers class from rest_framework and define fields for a serializer just like creating a form or model in Django.
Like @DanEEStart said, DjangoRestFramework don't have a simple way to extend the 'all' value for fields, because the get_field_names
methods seems to be designed to work that way.
But fortunately you can override this method to allow a simple way to include all fields and relations without enumerate a tons of fields.
I override this method like this:
class ToppingSerializer(serializers.ModelSerializer):
class Meta:
model = Topping
fields = '__all__'
extra_fields = ['pizzas']
def get_field_names(self, declared_fields, info):
expanded_fields = super(ToppingSerializer, self).get_field_names(declared_fields, info)
if getattr(self.Meta, 'extra_fields', None):
return expanded_fields + self.Meta.extra_fields
else:
return expanded_fields
Note that this method only change the behaviour of this serializer, and the extra_fields
attribute only works on this serializer class.
If you have a tons of serializer like this, you can create a intermediate class to include this get_fields_names
method in one place and reuse'em many times. Some like this:
class CustomSerializer(serializers.HyperlinkedModelSerializer):
def get_field_names(self, declared_fields, info):
expanded_fields = super(CustomSerializer, self).get_field_names(declared_fields, info)
if getattr(self.Meta, 'extra_fields', None):
return expanded_fields + self.Meta.extra_fields
else:
return expanded_fields
class ToppingSerializer(CustomSerializer):
class Meta:
model = Topping
fields = '__all__'
extra_fields = ['pizzas']
class AnotherSerializer(CustomSerializer):
class Meta:
model = Post
fields = '__all__'
extra_fields = ['comments']
I just checked the source code of Django Rest Framework. The behaviour you want seems not to be supported in the Framework.
The fields
option must be a list, a tuple or the text __all__
.
Here is a snippet of the relevant source code:
ALL_FIELDS = '__all__'
if fields and fields != ALL_FIELDS and not isinstance(fields, (list, tuple)):
raise TypeError(
'The `fields` option must be a list or tuple or "__all__". '
'Got %s.' % type(fields).__name__
)
You cannot add 'all' additionally to the tuple or list with fields...
The fields="__all__"
option can work by specifying an additional field manually as per the following examples. This is by far the cleanest solution around for this issue.
Nested Relationships
http://www.django-rest-framework.org/api-guide/relations/#nested-relationships
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = '__all__'
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)
class Meta:
model = Album
fields = '__all__'
I would assume this would work for any of the other related field options listed on the same page: http://www.django-rest-framework.org/api-guide/relations/#serializer-relations
Reverse relation example
class TrackSerializer(serializers.ModelSerializer):
album = AlbumSerializer(source='album_id')
class Meta:
model = Track
fields = '__all__'
Note: Created using Django Rest Framework version 3.6.2, subject to change. Please add a comment if any future changes break any examples posted above.
Hi I could achieve the expected result by using Django's _meta API , which seems to be available since Django 1.11. So in my serializer I did:
model = MyModel
fields = [field.name for field in model._meta.fields]
fields.append('any_other_field')
In programming there's always many ways to achieve the same result, but this one above, has really worked for me.
Cheers!
If you are trying to basically just add extra piece of information into the serialized object, you don't need to change the fields part at all. To add a field you do:
class MySerializer(serializers.ModelSerializer):
...
new_field = serializers.SerializerMethodField('new_field_method')
def new_field_method(self, modelPointer_):
return "MY VALUE"
Then you can still use
class Meta:
fields = '__all__'
to include all the fields and the other fields defined in your serializer you can just say exclude = ()
class ToppingSerializer(serializers.HyperlinkedModelSerializer):
pizzas = '<>' #the extra attribute value
class Meta:
model = Topping
exclude = ()
This will list all the field values with the extra argument pizzas
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With