Skip to content

Requests client #4406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ You may also want to [follow the author on Twitter][twitter].

# Security

If you believe youve found something in Django REST framework which has security implications, please **do not raise the issue in a public forum**.
If you believe you've found something in Django REST framework which has security implications, please **do not raise the issue in a public forum**.

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.

Expand Down
7 changes: 6 additions & 1 deletion docs/api-guide/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Or, if you're using the `@api_view` decorator with function based views.
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

@api_view('GET')
@api_view(['GET'])
@permission_classes((IsAuthenticated, ))
def example_view(request, format=None):
content = {
Expand Down Expand Up @@ -261,6 +261,10 @@ The [REST Condition][rest-condition] package is another extension for building c

The [DRY Rest Permissions][dry-rest-permissions] package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrive per user.

## Django Rest Framework Roles

The [Django Rest Framework Roles][django-rest-framework-roles] package makes it easier to parameterize your API over multiple types of users.

[cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html
[authentication]: authentication.md
[throttling]: throttling.md
Expand All @@ -275,3 +279,4 @@ The [DRY Rest Permissions][dry-rest-permissions] package provides the ability to
[composed-permissions]: https://github.com/niwibe/djangorestframework-composed-permissions
[rest-condition]: https://github.com/caxap/rest_condition
[dry-rest-permissions]: https://github.com/Helioscene/dry-rest-permissions
[django-rest-framework-roles]: https://github.com/computer-lab/django-rest-framework-roles
25 changes: 25 additions & 0 deletions docs/topics/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ You can determine your currently installed version using `pip freeze`:

## 3.4.x series

### 3.4.5

**Date**: [19th August 2016][3.4.5-milestone]

* Improve debug error handling. ([#4416][gh4416], [#4409][gh4409])
* Allow custom CSRF_HEADER_NAME setting. ([#4415][gh4415], [#4410][gh4410])
* Include .action attribute on viewsets when generating schemas. ([#4408][gh4408], [#4398][gh4398])
* Do not include request.FILES items in request.POST. ([#4407][gh4407])
* Fix rendering of checkbox multiple. ([#4403][gh4403])
* Fix docstring of Field.get_default. ([#4404][gh4404])
* Replace utf8 character with its ascii counterpart in README. ([#4412][gh4412])

### 3.4.4

**Date**: [12th August 2016][3.4.4-milestone]
Expand Down Expand Up @@ -560,6 +572,7 @@ For older release notes, [please see the version 2.x documentation][old-release-
[3.4.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.2+Release%22
[3.4.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.3+Release%22
[3.4.4-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.4+Release%22
[3.4.5-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.4.5+Release%22

<!-- 3.0.1 -->
[gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013
Expand Down Expand Up @@ -1065,3 +1078,15 @@ For older release notes, [please see the version 2.x documentation][old-release-
[gh4392]: https://github.com/tomchristie/django-rest-framework/issues/4392
[gh4393]: https://github.com/tomchristie/django-rest-framework/issues/4393
[gh4394]: https://github.com/tomchristie/django-rest-framework/issues/4394

<!-- 3.4.5 -->
[gh4416]: https://github.com/tomchristie/django-rest-framework/issues/4416
[gh4409]: https://github.com/tomchristie/django-rest-framework/issues/4409
[gh4415]: https://github.com/tomchristie/django-rest-framework/issues/4415
[gh4410]: https://github.com/tomchristie/django-rest-framework/issues/4410
[gh4408]: https://github.com/tomchristie/django-rest-framework/issues/4408
[gh4398]: https://github.com/tomchristie/django-rest-framework/issues/4398
[gh4407]: https://github.com/tomchristie/django-rest-framework/issues/4407
[gh4403]: https://github.com/tomchristie/django-rest-framework/issues/4403
[gh4404]: https://github.com/tomchristie/django-rest-framework/issues/4404
[gh4412]: https://github.com/tomchristie/django-rest-framework/issues/4412
2 changes: 1 addition & 1 deletion requirements/requirements-optionals.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
markdown==2.6.4
django-guardian==1.4.3
django-filter==0.13.0
coreapi==1.32.0
coreapi==2.0.0
2 changes: 1 addition & 1 deletion rest_framework/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"""

__title__ = 'Django REST framework'
__version__ = '3.4.4'
__version__ = '3.4.5'
__author__ = 'Tom Christie'
__license__ = 'BSD 2-Clause'
__copyright__ = 'Copyright 2011-2016 Tom Christie'
Expand Down
7 changes: 7 additions & 0 deletions rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ def value_from_object(field, obj):
uritemplate = None


# requests is optional
try:
import requests
except ImportError:
requests = None


# Django-guardian is optional. Import only if guardian is in INSTALLED_APPS
# Fixes (#1712). We keep the try/except for the test suite.
guardian = None
Expand Down
2 changes: 1 addition & 1 deletion rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ def get_default(self):
is provided for this field.

If a default has not been set for this field then this will simply
return `empty`, indicating that no value should be set in the
raise `SkipField`, indicating that no value should be set in the
validated data for this field.
"""
if self.default is empty or getattr(self.root, 'partial', False):
Expand Down
6 changes: 5 additions & 1 deletion rest_framework/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from django.db.models import Manager
from django.db.models.query import QuerySet
from django.utils import six
from django.utils.encoding import smart_text
from django.utils.encoding import python_2_unicode_compatible, smart_text
from django.utils.six.moves.urllib import parse as urlparse
from django.utils.translation import ugettext_lazy as _

Expand Down Expand Up @@ -47,6 +47,7 @@ def __getnewargs__(self):
is_hyperlink = True


@python_2_unicode_compatible
class PKOnlyObject(object):
"""
This is a mock object, used for when we only need the pk of the object
Expand All @@ -56,6 +57,9 @@ class PKOnlyObject(object):
def __init__(self, pk):
self.pk = pk

def __str__(self):
return "%s" % self.pk


# We assume that 'validators' are intended for the child serializer,
# rather than the parent serializer.
Expand Down
9 changes: 8 additions & 1 deletion rest_framework/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,12 @@ def get_context(self, data, accepted_media_type, renderer_context):
else:
paginator = None

csrf_cookie_name = settings.CSRF_COOKIE_NAME
csrf_header_name = getattr(settings, 'CSRF_HEADER_NAME', 'HTTP_X_CSRFToken') # Fallback for Django 1.8
if csrf_header_name.startswith('HTTP_'):
csrf_header_name = csrf_header_name[5:]
csrf_header_name = csrf_header_name.replace('_', '-')

context = {
'content': self.get_content(renderer, data, accepted_media_type, renderer_context),
'view': view,
Expand Down Expand Up @@ -675,7 +681,8 @@ def get_context(self, data, accepted_media_type, renderer_context):
'display_edit_forms': bool(response.status_code != 403),

'api_settings': api_settings,
'csrf_cookie_name': settings.CSRF_COOKIE_NAME,
'csrf_cookie_name': csrf_cookie_name,
'csrf_header_name': csrf_header_name
}
return context

Expand Down
7 changes: 6 additions & 1 deletion rest_framework/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def POST(self):
if not _hasattr(self, '_data'):
self._load_data_and_files()
if is_form_media_type(self.content_type):
return self.data
return self._data
return QueryDict('', encoding=self._request._encoding)

@property
Expand All @@ -391,3 +391,8 @@ def QUERY_PARAMS(self):
'`request.QUERY_PARAMS` has been deprecated in favor of `request.query_params` '
'since version 3.0, and has been fully removed as of version 3.2.'
)

def force_plaintext_errors(self, value):
# Hack to allow our exception handler to force choice of
# plaintext or html error responses.
self._request.is_ajax = lambda: value
7 changes: 7 additions & 0 deletions rest_framework/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ def get_schema(self, request=None):
view.kwargs = {}
view.format_kwarg = None

actions = getattr(callback, 'actions', None)
if actions is not None:
if method == 'OPTIONS':
view.action = 'metadata'
else:
view.action = actions.get(method.lower())

if request is not None:
view.request = clone_request(request, method)
try:
Expand Down
8 changes: 5 additions & 3 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"""
from __future__ import unicode_literals

import traceback
import warnings

from django.db import models
Expand Down Expand Up @@ -870,19 +871,20 @@ def create(self, validated_data):

try:
instance = ModelClass.objects.create(**validated_data)
except TypeError as exc:
except TypeError:
tb = traceback.format_exc()
msg = (
'Got a `TypeError` when calling `%s.objects.create()`. '
'This may be because you have a writable field on the '
'serializer class that is not a valid argument to '
'`%s.objects.create()`. You may need to make the field '
'read-only, or override the %s.create() method to handle '
'this correctly.\nOriginal exception text was: %s.' %
'this correctly.\nOriginal exception was:\n %s' %
(
ModelClass.__name__,
ModelClass.__name__,
self.__class__.__name__,
exc
tb
)
)
raise TypeError(msg)
Expand Down
2 changes: 1 addition & 1 deletion rest_framework/static/rest_framework/js/csrf.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ $.ajaxSetup({
// Send the token to same-origin, relative URLs only.
// Send the token only if the method warrants CSRF protection
// Using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.setRequestHeader(window.drf.csrfHeaderName, csrftoken);
}
}
});
1 change: 1 addition & 0 deletions rest_framework/templates/rest_framework/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ <h4 class="modal-title" id="myModalLabel">{{ error_title }}</h4>
{% block script %}
<script>
window.drf = {
csrfHeaderName: "{{ csrf_header_name|default:'X-CSRFToken' }}"
csrfCookieName: "{{ csrf_cookie_name|default:'csrftoken' }}"
};
</script>
Expand Down
1 change: 1 addition & 0 deletions rest_framework/templates/rest_framework/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ <h1>{{ name }}</h1>
{% block script %}
<script>
window.drf = {
csrfHeaderName: "{{ csrf_header_name|default:'X-CSRFToken' }}"
csrfCookieName: "{{ csrf_cookie_name|default:'csrftoken' }}"
};
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div>
{% for key, text in field.choices.items %}
<label class="checkbox-inline">
<input type="checkbox" name="{{ field.name }}" value="{{ key }}" {% if key|as_string in field.value|as_list_of_stringsg %}checked{% endif %}>
<input type="checkbox" name="{{ field.name }}" value="{{ key }}" {% if key|as_string in field.value|as_list_of_strings %}checked{% endif %}>
{{ text }}
</label>
{% endfor %}
Expand All @@ -18,7 +18,7 @@
{% for key, text in field.choices.items %}
<div class="checkbox">
<label>
<input type="checkbox" name="{{ field.name }}" value="{{ key }}" {% if key|as_string in field.value|as_list_of_stringsg %}checked{% endif %}>
<input type="checkbox" name="{{ field.name }}" value="{{ key }}" {% if key|as_string in field.value|as_list_of_strings %}checked{% endif %}>
{{ text }}
</label>
</div>
Expand Down
Loading