Coverage for rest_framework/serializers : + 94% +
+
+ From 3d4bb4b5533fa281c2f11c12ceb0a9ae61aa0d54 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 21 Jun 2013 22:03:07 +0100 Subject: Ensure action kwargs properly handdled. Refs #940. --- htmlcov/rest_framework_serializers.html | 2011 +++++++++++++++++++++++++++++++ 1 file changed, 2011 insertions(+) create mode 100644 htmlcov/rest_framework_serializers.html (limited to 'htmlcov/rest_framework_serializers.html') diff --git a/htmlcov/rest_framework_serializers.html b/htmlcov/rest_framework_serializers.html new file mode 100644 index 00000000..79dc5647 --- /dev/null +++ b/htmlcov/rest_framework_serializers.html @@ -0,0 +1,2011 @@ + + +
+ + + + +
+
+Hot-keys on this page
++ r + m + x + p toggle line displays +
++ j + k next/prev highlighted chunk +
++ 0 (zero) top of page +
++ 1 (one) first highlighted chunk +
+| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + | +
+ """ +Serializers and ModelSerializers are similar to Forms and ModelForms. +Unlike forms, they are not constrained to dealing with HTML output, and +form encoded input. ++ Serialization in REST framework is a two-phase process: ++ 1. Serializers marshal between complex types like model instances, and +python primatives. +2. The process of marshalling between python primatives and request and +response content is handled by parsers and renderers. +""" + + + + + + + + + + ++ # Note: We do the following so that users of the framework can use this style: +# +# example_field = serializers.CharField(...) +# +# This helps keep the separation between model fields, form fields, and +# serializer fields more explicit. ++ + + + + + """ +The default ValidationError behavior is to stringify each item in the list +if the messages are a list of error messages. ++ In the case of nested serializers, where the parent has many children, +then the child's `serializer.errors` will be a list of dicts. In the case +of a single child, the `serializer.errors` will be a dict. ++ We need to override the default behavior to get properly nested error dicts. +""" ++ + + self.messages = [message] +else: + ++ + + """ +A dict-like object, that can have additional properties attached. +""" + +""" +Used by pickle (e.g., caching). +Overridden to remove the metadata from the dict, since it shouldn't be +pickled and may in some instances be unpickleable. +""" + ++ + + """ +A sorted dict-like object, that can have additional properties attached. +""" + +""" +Used by pickle (e.g., caching). +Overriden to remove the metadata from the dict, since it shouldn't be +pickle and may in some instances be unpickleable. +""" + ++ + + """ +True if the object is a native datatype that does not need to +be serialized further. +""" +return isinstance(obj, ( +types.NoneType, +int, long, +datetime.datetime, datetime.date, datetime.time, +float, Decimal, +basestring) +) ++ + + """ +Create a list of serializer field instances from the passed in 'attrs', +plus any fields on the base classes (in 'bases'). ++ Note that all fields from the base classes are used. +""" + +for field_name, obj in list(six.iteritems(attrs)) +if isinstance(obj, Field)] + ++ # If this class is subclassing another Serializer, add that Serializer's +# fields. Note that we loop over the bases in *reverse*. This is necessary +# in order to maintain the correct order of fields. + + + ++ + + + + + + + + + + """ +Meta class options for Serializer +""" + + + + ++ + + """ +This is the Serializer implementation. +We need to implement it as `BaseSerializer` due to metaclass magicks. +""" + + ++ + + + + context=None, partial=False, many=None, +allow_add_remove=False, **kwargs): + + + + + + + ++ + + + + + + + + + + + + + raise ValueError('instance should be a queryset or other iterable with many=True') ++ + raise ValueError('allow_add_remove should only be used for bulk updates, but you have not set many=True') ++ ##### +# Methods to determine which fields to use when (de)serializing objects. ++ + """ +Return the complete set of default fields for the object, as a dict. +""" + ++ + """ +Returns the complete set of fields for the object as a dict. ++ This will be the set of any explicitly declared fields, +plus the set of fields returned by get_default_fields(). +""" + ++ # Get the explicitly declared fields + + + ++ # Add in the default fields + + + + ++ # If 'fields' is specified, use those fields, in that order. + + + + + + ++ # Remove anything in 'exclude' + + + + ++ + + + + + ##### +# Methods to convert or revert from objects <--> primitive representations. ++ + """ +Return the key that should be used for a given field. +""" + ++ + """ +Core of deserialization, together with `restore_object`. +Converts a dictionary of data into a dictionary of deserialized fields. +""" + ++ + + + + + + + + + + + + + + """ +Run `validate_<fieldname>()` and `validate()` methods on the serializer +""" + + + + + + + + + + ++ # If there are already errors, we don't run .validate() because +# field-validation failed and thus `attrs` may not be complete. +# which in turn can cause inconsistent validation errors. + + + + + +for field_name, error_messages in err.message_dict.items(): +self._errors[field_name] = self._errors.get(field_name, []) + list(error_messages) + + ++ + + + """ +Stub method, to be overridden in Serializer subclasses +""" + ++ + """ +Deserialize a dictionary of attributes into an object instance. +You should override this method to control how deserialized objects +are instantiated. +""" + +instance.update(attrs) +return instance + ++ + """ +Serialize objects -> primitives. +""" + + ++ + + + + + + + + + """ +Deserialize primitives -> objects. +""" + + + + + +else: +self._errors['non_field_errors'] = ['No input provided'] ++ + + + + """ +Override default so that the serializer can be used as a nested field +across relationships. +""" + + ++ + + + + + + + + + + + + + + + + + + + else: + ++ + + + + + """ +Override default so that the serializer can be used as a writable +nested field across relationships. +""" + +return ++ + + + + # Note: partial updates shouldn't set defaults +value = copy.deepcopy(self.default) +else: + +raise ValidationError(self.error_messages['required']) + ++ # Set the serializer object if it exists + ++ + + + else: + +into[(self.source or field_name)] = None +else: + +'instance': obj, +'data': value, +'context': self.context, +'partial': self.partial, +'many': self.many +} + ++ + + else: +# Propagate errors up to our parent + ++ + """ +This hook is required for bulk update. +It is used to determine the canonical identity of a given object. ++ Note that the data has not been validated at this point, so we need +to make sure that we catch any cases of incorrect datatypes being +passed to this method. +""" + + +except AttributeError: +return None ++ + def errors(self): +""" +Run deserialization and return error data, +setting self.object if no errors occurred. +""" + + ++ + + else: + + +warnings.warn('Implict list/queryset serialization is deprecated. ' +'Use the `many=True` flag when instantiating the serializer.', +DeprecationWarning, stacklevel=3) ++ + + + + + + # If this is a bulk update we need to map all the objects +# to a canonical identity so we can determine which +# individual object is being updated for each item in the +# incoming data + + + ++ + + + # Determine which object we're updating + + + + + + ++ + + + + + + + else: + +else: + ++ + + + + + + + + + def data(self): +""" +Returns the serialized data on the serializer. +""" + + ++ + + else: + + +warnings.warn('Implict list/queryset serialization is deprecated. ' +'Use the `many=True` flag when instantiating the serializer.', +DeprecationWarning, stacklevel=2) ++ + + else: + ++ + + + + + + + + + """ +Save the deserialized object and return it. +""" + + +else: + ++ + + + + + + """ +Return a dictionary of metadata about the fields on the serializer. +Useful for things like responding to OPTIONS requests, or generating +API schemas for auto-documentation. +""" + +[(field_name, field.metadata()) +for field_name, field in six.iteritems(self.fields)] +) ++ + + + + + + """ +Meta class options for ModelSerializer +""" + + + + ++ + + """ +A serializer that deals with model instances and querysets. +""" + ++ + models.AutoField: IntegerField, +models.FloatField: FloatField, +models.IntegerField: IntegerField, +models.PositiveIntegerField: IntegerField, +models.SmallIntegerField: IntegerField, +models.PositiveSmallIntegerField: IntegerField, +models.DateTimeField: DateTimeField, +models.DateField: DateField, +models.TimeField: TimeField, +models.DecimalField: DecimalField, +models.EmailField: EmailField, +models.CharField: CharField, +models.URLField: URLField, +models.SlugField: SlugField, +models.TextField: CharField, +models.CommaSeparatedIntegerField: CharField, +models.BooleanField: BooleanField, +models.FileField: FileField, +models.ImageField: ImageField, +} ++ + """ +Return all the fields that should be serialized for the model. +""" ++ + + "Serializer class '%s' is missing 'model' Meta option" % self.__class__.__name__ + + + ++ # Deal with adding the primary key field + + +# If model is a child via multitable inheritance, use parent's pk + ++ + + + + # Deal with forward relationships + + ++ + + + + + models.fields.related.ManyToManyField) + ++ + + + + + warnings.warn( +'The `get_nested_field(model_field)` call signature ' +'is due to be deprecated. ' +'Use `get_nested_field(model_field, related_model, ' +'to_many) instead', +PendingDeprecationWarning +) +field = self.get_nested_field(model_field) +else: + + + +warnings.warn( +'The `get_related_field(model_field, to_many)` call ' +'signature is due to be deprecated. ' +'Use `get_related_field(model_field, related_model, ' +'to_many) instead', +PendingDeprecationWarning +) +field = self.get_related_field(model_field, to_many=to_many) +else: + +else: + ++ + + + + + + # Deal with reverse relationships + + +else: +# Reverse relationships are only included if they are explicitly +# present in the `fields` option on the serializer + + ++ + + + + + + + + models.fields.related.ManyToManyField) ++ + + + + + else: + ++ + + + + + + # Add the `read_only` flag to any fields that have bee specified +# in the `read_only_fields` option + + +"field '%s' on serializer '%s' specfied in " \ +"`read_only_fields`, but also added " \ +"as an explict field. Remove it from `read_only_fields`." % \ +(field_name, self.__class__.__name__) + +"Noexistant field '%s' specified in `read_only_fields` " \ +"on serializer '%s'." % \ +(self.__class__.__name__, field_name) + ++ + + + """ +Returns a default instance of the pk field. +""" + ++ + """ +Creates a default instance of a nested relational field. ++ Note that model_field will be `None` for reverse relationships. +""" + + + + ++ + + + """ +Creates a default instance of a flat relational field. ++ Note that model_field will be `None` for reverse relationships. +""" +# TODO: filter queryset using: +# .using(db).complex_filter(self.rel.limit_choices_to) ++ + 'queryset': related_model._default_manager, +'many': to_many +} ++ + + + + + + """ +Creates a default instance of a basic non-relational field. +""" + ++ + + + + + + + + + + + + + + + + + + # TODO: TypedChoiceField? + + + ++ # put this below the ChoiceField because min_value isn't a valid initializer + +issubclass(model_field.__class__, models.PositiveSmallIntegerField): + ++ + models.CharField: ['max_length'], +models.CommaSeparatedIntegerField: ['max_length'], +models.DecimalField: ['max_digits', 'decimal_places'], +models.EmailField: ['max_length'], +models.FileField: ['max_length'], +models.ImageField: ['max_length'], +models.SlugField: ['max_length'], +models.URLField: ['max_length'], +} ++ + + + + + + + + + + + """ +Return a list of field names to exclude from model validation. +""" + + + + + + + + ++ + """ +Perform Django's full_clean, and populate the `errors` dictionary +if any validation errors occur. ++ Note that we don't perform this inside the `.restore_object()` method, +so that subclasses can override `.restore_object()`, and still get +the full_clean validation checking. +""" + + + + + + ++ + """ +Restore the model instance. +""" + + + ++ # Reverse fk or one-to-one relations + + + + ++ # Reverse m2m relations + + + + ++ # Forward m2m relations + + + ++ # Update an existing instance... + + + ++ # ...or create a new instance +else: + ++ # Any relations that cannot be set until we've +# saved the model get hidden away on these +# private attributes, so we can deal with them +# at the point of save. + + ++ + + + """ +Override the default method to also include model field validation. +""" + + + ++ + """ +Save the deserialized object and return it. +""" + ++ + + + + + + + + + + + + """ +Options for HyperlinkedModelSerializer +""" + + + + ++ + + """ +A subclass of ModelSerializer that uses hyperlinked relationships, +instead of primary key relationships. +""" + + + ++ + + + + + + + + view_name=self.opts.view_name, +lookup_field=self.opts.lookup_field +) + ++ + + + + return self.get_field(model_field) ++ + """ +Creates a default instance of a flat relational field. +""" +# TODO: filter queryset using: +# .using(db).complex_filter(self.rel.limit_choices_to) + +'queryset': related_model._default_manager, +'view_name': self._get_default_view_name(related_model), +'many': to_many +} ++ + + + + kwargs['lookup_field'] = self.opts.lookup_field ++ + + + """ +This hook is required for bulk update. +We need to override the default, to use the url as the identity. +""" +try: +return data.get('url', None) +except AttributeError: +return None ++ + """ +Return the view name to use if 'view_name' is not specified in 'Meta' +""" + + +'app_label': model_meta.app_label, +'model_name': model_meta.object_name.lower() +} + + + |
+