Skip to content

Commit

Permalink
Merge branch 'master' into filters
Browse files Browse the repository at this point in the history
Conflicts:
	rest_framework/compat.py
	rest_framework/filters.py
  • Loading branch information
tomchristie committed Oct 19, 2015
2 parents f34777a + 86470b7 commit 34eb18b
Show file tree
Hide file tree
Showing 144 changed files with 5,752 additions and 2,790 deletions.
25 changes: 6 additions & 19 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ sudo: false
env:
- TOX_ENV=py27-lint
- TOX_ENV=py27-docs
- TOX_ENV=py35-django19
- TOX_ENV=py34-django19
- TOX_ENV=py27-django19
- TOX_ENV=py34-django18
- TOX_ENV=py33-django18
- TOX_ENV=py32-django18
Expand All @@ -13,28 +16,12 @@ env:
- TOX_ENV=py33-django17
- TOX_ENV=py32-django17
- TOX_ENV=py27-django17
- TOX_ENV=py34-django16
- TOX_ENV=py33-django16
- TOX_ENV=py32-django16
- TOX_ENV=py27-django16
- TOX_ENV=py26-django16
- TOX_ENV=py34-django15
- TOX_ENV=py33-django15
- TOX_ENV=py32-django15
- TOX_ENV=py27-django15
- TOX_ENV=py26-django15
- TOX_ENV=py27-djangomaster
- TOX_ENV=py32-djangomaster
- TOX_ENV=py33-djangomaster
- TOX_ENV=py34-djangomaster

matrix:
# Python 3.5 not yet available on travis, watch this to see when it is.
fast_finish: true
allow_failures:
- env: TOX_ENV=py27-djangomaster
- env: TOX_ENV=py32-djangomaster
- env: TOX_ENV=py33-djangomaster
- env: TOX_ENV=py34-djangomaster
- env: TOX_ENV=py35-django19

install:
- pip install tox
Expand All @@ -44,4 +31,4 @@ script:

after_success:
- pip install codecov
- codecov
- codecov -e TOX_ENV
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ There is a live example API for testing purposes, [available here][sandbox].

# Requirements

* Python (2.6.5+, 2.7, 3.2, 3.3, 3.4)
* Django (1.5.6+, 1.6.3+, 1.7, 1.8)
* Python (2.7, 3.2, 3.3, 3.4, 3.5)
* Django (1.7, 1.8, 1.9)

# Installation

Expand Down Expand Up @@ -157,7 +157,6 @@ If you believe you’ve found something in Django REST framework which has secur

Send a description of the issue via email to [[email protected]][security-mail]. The project maintainers will then work with you to resolve any issues where required, prior to any public disclosure.


[build-status-image]: https://secure.travis-ci.org/tomchristie/django-rest-framework.svg?branch=master
[travis]: http://travis-ci.org/tomchristie/django-rest-framework?branch=master
[coverage-status-image]: https://img.shields.io/codecov/c/github/tomchristie/django-rest-framework/master.svg
Expand Down
10 changes: 10 additions & 0 deletions docs/api-guide/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a

[Django-rest-auth][django-rest-auth] library provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc. By having these API endpoints, your client apps such as AngularJS, iOS, Android, and others can communicate to your Django backend site independently via REST APIs for user management.

## django-rest-framework-social-oauth2

[Django-rest-framework-social-oauth2][django-rest-framework-social-oauth2] library provides an easy way to integrate social plugins (facebook, twitter, google, etc.) to your authentication system and an easy oauth2 setup. With this library, you will be able to authenticate users based on external tokens (e.g. facebook access token), convert these tokens to "in-house" oauth2 tokens and use and generate oauth2 tokens to authenticate your users.

## django-rest-knox

[Django-rest-knox][django-rest-knox] library provides models and views to handle token based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a user is logged into).

[cite]: http://jacobian.org/writing/rest-worst-practices/
[http401]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
[http403]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4
Expand Down Expand Up @@ -400,3 +408,5 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
[mac]: http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05
[djoser]: https://github.com/sunscrapers/djoser
[django-rest-auth]: https://github.com/Tivix/django-rest-auth
[django-rest-framework-social-oauth2]: https://github.com/PhilipGarnero/django-rest-framework-social-oauth2
[django-rest-knox]: https://github.com/James1345/django-rest-knox
12 changes: 10 additions & 2 deletions docs/api-guide/fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ Defaults to `False`

If set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behavior is to not populate the attribute at all.

May be set to a function or other callable, in which case the value will be evaluated each time it is used.
May be set to a function or other callable, in which case the value will be evaluated each time it is used. When called, it will receive no arguments. If the callable has a `set_context` method, that will be called each time before getting the value with the field instance as only argument. This works the same way as for [validators](validators.md#using-set_context).

Note that setting a `default` value implies that the field is not required. Including both the `default` and `required` keyword arguments is invalid and will raise an error.

### `source`

The name of the attribute that will be used to populate the field. May be a method that only takes a `self` argument, such as `URLField('get_absolute_url')`, or may use dotted notation to traverse attributes, such as `EmailField(source='user.email')`.
The name of the attribute that will be used to populate the field. May be a method that only takes a `self` argument, such as `URLField(source='get_absolute_url')`, or may use dotted notation to traverse attributes, such as `EmailField(source='user.email')`.

The value `source='*'` has a special meaning, and is used to indicate that the entire object should be passed through to the field. This can be useful for creating nested representations, or for fields which require access to the complete object in order to determine the output representation.

Expand Down Expand Up @@ -459,6 +459,14 @@ You can also use the declarative style, as with `ListField`. For example:
class DocumentField(DictField):
child = CharField()

## JSONField

A field class that validates that the incoming data structure consists of valid JSON primitives. In its alternate binary mode, it will represent and validate JSON-encoded binary strings.

**Signature**: `JSONField(binary)`

- `binary` - If set to `True` then the field will output and validate a JSON encoded string, rather that a primitive data structure. Defaults to `False`.

---

# Miscellaneous fields
Expand Down
7 changes: 5 additions & 2 deletions docs/api-guide/filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,6 @@ The `ordering` attribute may be either a string or a list/tuple of strings.

The `DjangoObjectPermissionsFilter` is intended to be used together with the [`django-guardian`][guardian] package, with custom `'view'` permissions added. The filter will ensure that querysets only returns objects for which the user has the appropriate view permission.

This filter class must be used with views that provide either a `queryset` or a `model` attribute.

If you're using `DjangoObjectPermissionsFilter`, you'll probably also want to add an appropriate object permissions class, to ensure that users can only operate on instances if they have the appropriate object permissions. The easiest way to do this is to subclass `DjangoObjectPermissions` and add `'view'` permissions to the `perms_map` attribute.

A complete example using both `DjangoObjectPermissionsFilter` and `DjangoObjectPermissions` might look something like this.
Expand Down Expand Up @@ -403,6 +401,10 @@ The [django-rest-framework-filters package][django-rest-framework-filters] works

The [djangorestframework-word-filter][django-rest-framework-word-search-filter] developed as alternative to `filters.SearchFilter` which will search full word in text, or exact match.

## Django URL Filter

[django-url-filter][django-url-filter] provides a safe way to filter data via human-friendly URLs. It works very similar to DRF serializers and fields in a sense that they can be nested except they are called filtersets and filters. That provides easy way to filter related data. Also this library is generic-purpose so it can be used to filter other sources of data and not only Django `QuerySet`s.

[cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters
[django-filter]: https://github.com/alex/django-filter
[django-filter-docs]: https://django-filter.readthedocs.org/en/latest/index.html
Expand All @@ -413,3 +415,4 @@ The [djangorestframework-word-filter][django-rest-framework-word-search-filter]
[search-django-admin]: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields
[django-rest-framework-filters]: https://github.com/philipn/django-rest-framework-filters
[django-rest-framework-word-search-filter]: https://github.com/trollknurr/django-rest-framework-word-search-filter
[django-url-filter]: https://github.com/miki725/django-url-filter
10 changes: 10 additions & 0 deletions docs/api-guide/format-suffixes.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ If using the `i18n_patterns` function provided by Django, as well as `format_suf

---

## Query parameter formats

An alternative to the format suffixes is to include the requested format in a query parameter. REST framework provides this option by default, and it is used in the browsable API to switch between differing available representations.

To select a representation using its short format, use the `format` query parameter. For example: `http://example.com/organizations/?format=csv`.

The name of this query parameter can be modified using the `URL_FORMAT_OVERRIDE` setting. Set the value to `None` to disable this behavior.

---

## Accept headers vs. format suffixes

There seems to be a view among some of the Web community that filename extensions are not a RESTful pattern, and that `HTTP Accept` headers should always be used instead.
Expand Down
12 changes: 7 additions & 5 deletions docs/api-guide/relations.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ For example, the following serializer:
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ('order', 'title')
fields = ('order', 'title', 'duration')

class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)
Expand Down Expand Up @@ -293,7 +293,7 @@ Be default nested serializers are read-only. If you want to to support write-ope
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ('order', 'title')
fields = ('order', 'title', 'duration')

class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True)
Expand Down Expand Up @@ -405,13 +405,15 @@ In this case we'd need to override `HyperlinkedRelatedField` to get the behavior
def get_url(self, obj, view_name, request, format):
url_kwargs = {
'organization_slug': obj.organization.slug,
'customer_pk': obj.pk }
'customer_pk': obj.pk
}
return reverse(view_name, url_kwargs, request=request, format=format)

def get_object(self, view_name, view_args, view_kwargs):
lookup_kwargs = {
'organization__slug': view_kwargs['organization_slug'],
'pk': view_kwargs['customer_pk'] }
'pk': view_kwargs['customer_pk']
}
return self.get_queryset().get(**lookup_kwargs)

Note that if you wanted to use this style together with the generic views then you'd also need to override `.get_object` on the view in order to get the correct lookup behavior.
Expand Down Expand Up @@ -501,7 +503,7 @@ For example, given the following model for a tag, which has a generic relationsh
tagged_object = GenericForeignKey('content_type', 'object_id')

def __unicode__(self):
return self.tag
return self.tag_name

And the following two models, which may be have associated tags:

Expand Down
49 changes: 43 additions & 6 deletions docs/api-guide/serializers.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ Your `validate_<field_name>` methods should return the validated value or raise
raise serializers.ValidationError("Blog post is not about Django")
return value

---

**Note:** If your `<field_name>` is declared on your serializer with the parameter `required=False` then this validation step will not take place if the field is not included.

---

#### Object-level validation

To do any other validation that requires access to multiple fields, add a method called `.validate()` to your `Serializer` subclass. This method takes a single argument, which is a dictionary of field values. It should raise a `ValidationError` if necessary, or just return the validated values. For example:
Expand Down Expand Up @@ -281,7 +287,7 @@ Similarly if a nested representation should be a list of items, you should pass

## Writable nested representations

When dealing with nested representations that support deserializing the data, an errors with nested objects will be nested under the field name of the nested object.
When dealing with nested representations that support deserializing the data, any errors with nested objects will be nested under the field name of the nested object.

serializer = CommentSerializer(data={'user': {'email': 'foobar', 'username': 'doe'}, 'content': 'baz'})
serializer.is_valid()
Expand Down Expand Up @@ -350,7 +356,7 @@ It is possible that a third party package, providing automatic support some kind

#### Handling saving related instances in model manager classes

An alternative to saving multiple related instances in the serializer is to write custom model manager classes handle creating the correct instances.
An alternative to saving multiple related instances in the serializer is to write custom model manager classes that handle creating the correct instances.

For example, suppose we wanted to ensure that `User` instances and `Profile` instances are always created together as a pair. We might write a custom manager class that looks something like this:

Expand Down Expand Up @@ -432,6 +438,7 @@ Declaring a `ModelSerializer` looks like this:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('id', 'account_name', 'users', 'created')

By default, all the model fields on the class will be mapped to a corresponding serializer fields.

Expand All @@ -453,7 +460,7 @@ To do so, open the Django shell, using `python manage.py shell`, then import the

## Specifying which fields to include

If you only want a subset of the default fields to be used in a model serializer, you can do so using `fields` or `exclude` options, just as you would with a `ModelForm`.
If you only want a subset of the default fields to be used in a model serializer, you can do so using `fields` or `exclude` options, just as you would with a `ModelForm`. It is strongly recommended that you explicitly set all fields that should be serialized using the `fields` attribute. This will make it less likely to result in unintentionally exposing data when your models change.

For example:

Expand All @@ -462,7 +469,27 @@ For example:
model = Account
fields = ('id', 'account_name', 'users', 'created')

The names in the `fields` option will normally map to model fields on the model class.
You can also set the `fields` attribute to the special value `'__all__'` to indicate that all fields in the model should be used.

For example:

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = '__all__'

You can set the `exclude` attribute to a list of fields to be excluded from the serializer.

For example:

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
exclude = ('users',)

In the example above, if the `Account` model had 3 fields `account_name`, `users`, and `created`, this will result in the fields `account_name` and `created` to be serialized.

The names in the `fields` and `exclude` attributes will normally map to model fields on the model class.

Alternatively names in the `fields` options can map to properties or methods which take no arguments that exist on the model class.

Expand Down Expand Up @@ -524,7 +551,7 @@ Please review the [Validators Documentation](/api-guide/validators/) for details

## Additional keyword arguments

There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. Similarly to `read_only_fields` this means you do not need to explicitly declare the field on the serializer.
There is also a shortcut allowing you to specify arbitrary additional keyword arguments on fields, using the `extra_kwargs` option. As in the case of `read_only_fields`, this means you do not need to explicitly declare the field on the serializer.

This option is a dictionary, mapping field names to a dictionary of keyword arguments. For example:

Expand Down Expand Up @@ -805,7 +832,7 @@ This class implements the same basic API as the `Serializer` class:
* `.data` - Returns the outgoing primitive representation.
* `.is_valid()` - Deserializes and validates incoming data.
* `.validated_data` - Returns the validated incoming data.
* `.errors` - Returns an errors during validation.
* `.errors` - Returns any errors during validation.
* `.save()` - Persists the validated data into an object instance.

There are four methods that can be overridden, depending on what functionality you want the serializer class to support:
Expand Down Expand Up @@ -1022,6 +1049,13 @@ A new interface for controlling this behavior is currently planned for REST fram

The following third party packages are also available.

## Django REST marshmallow

The [django-rest-marshmallow][django-rest-marshmallow] package provides an alternative implementation for serializers, using the python [marshmallow][marshmallow] library. It exposes the same API as the REST framework serializers, and can be used as a drop-in replacement in some use-cases.

## Serpy
The [serpy][serpy] package is an alternative implementation for serializers that is built for speed. [Serpy][serpy] serializes complex datatypes to simple native types. The native types can be easily converted to JSON or any other format needed.

## MongoengineModelSerializer

The [django-rest-framework-mongoengine][mongoengine] package provides a `MongoEngineModelSerializer` serializer class that supports using MongoDB as the storage layer for Django REST framework.
Expand All @@ -1038,6 +1072,9 @@ The [django-rest-framework-hstore][django-rest-framework-hstore] package provide
[relations]: relations.md
[model-managers]: https://docs.djangoproject.com/en/dev/topics/db/managers/
[encapsulation-blogpost]: http://www.dabapps.com/blog/django-models-and-encapsulation/
[django-rest-marshmallow]: http://tomchristie.github.io/django-rest-marshmallow/
[marshmallow]: https://marshmallow.readthedocs.org/en/latest/
[serpy]: https://github.com/clarkduvall/serpy
[mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine
[django-rest-framework-gis]: https://github.com/djangonauts/django-rest-framework-gis
[django-rest-framework-hstore]: https://github.com/djangonauts/django-rest-framework-hstore
Expand Down
Loading

0 comments on commit 34eb18b

Please sign in to comment.