mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-26 19:43:59 +03:00
Merge remote-tracking branch 'upstream/master' into related-required
This commit is contained in:
commit
2f5582a1a6
|
@ -79,6 +79,7 @@ The following people have helped make REST framework great.
|
|||
* Colin Murtaugh - [cmurtaugh]
|
||||
* Simon Pantzare - [pilt]
|
||||
* Szymon Teżewski - [sunscrapers]
|
||||
* Joel Marcotte - [joual]
|
||||
|
||||
Many thanks to everyone who's contributed to the project.
|
||||
|
||||
|
@ -193,3 +194,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter.
|
|||
[cmurtaugh]: https://github.com/cmurtaugh
|
||||
[pilt]: https://github.com/pilt
|
||||
[sunscrapers]: https://github.com/sunscrapers
|
||||
[joual]: https://github.com/joual
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
### Master
|
||||
|
||||
* Bugfix: Fix bug that could occur using ChoiceField.
|
||||
* Bugfix: Fix exception in browseable API on DELETE.
|
||||
* Bugfix: Fix issue where pk was was being set to a string if set by URL kwarg.
|
||||
|
||||
### 2.1.11
|
||||
|
|
|
@ -5,6 +5,12 @@ versions of django/python, and compatibility wrappers around optional packages.
|
|||
# flake8: noqa
|
||||
import django
|
||||
|
||||
# location of patterns, url, include changes in 1.4 onwards
|
||||
try:
|
||||
from django.conf.urls import patterns, url, include
|
||||
except:
|
||||
from django.conf.urls.defaults import patterns, url, include
|
||||
|
||||
# django-filter is optional
|
||||
try:
|
||||
import django_filters
|
||||
|
|
|
@ -801,7 +801,7 @@ class ChoiceField(WritableField):
|
|||
if value == smart_unicode(k2):
|
||||
return True
|
||||
else:
|
||||
if value == smart_unicode(k):
|
||||
if value == smart_unicode(k) or value == k:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
@ -124,6 +124,6 @@ class DestroyModelMixin(object):
|
|||
Should be mixed in with `SingleObjectBaseView`.
|
||||
"""
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
self.object.delete()
|
||||
obj = self.get_object()
|
||||
obj.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
from django.conf.urls.defaults import patterns
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import Client, TestCase
|
||||
|
||||
from django.utils import simplejson as json
|
||||
from django.http import HttpResponse
|
||||
from django.test import Client, TestCase
|
||||
from django.utils import simplejson as json
|
||||
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import permissions
|
||||
|
||||
from rest_framework.authtoken.models import Token
|
||||
from rest_framework.authentication import TokenAuthentication
|
||||
from rest_framework.compat import patterns
|
||||
from rest_framework.views import APIView
|
||||
|
||||
import base64
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from django.test import TestCase
|
||||
from rest_framework.compat import patterns, url
|
||||
from rest_framework.utils.breadcrumbs import get_breadcrumbs
|
||||
from rest_framework.views import APIView
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from django.test.client import RequestFactory
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
from rest_framework.parsers import JSONParser
|
||||
from rest_framework.authentication import BasicAuthentication
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from django.core.exceptions import PermissionDenied
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
from django.http import Http404
|
||||
from django.test import TestCase
|
||||
from django.template import TemplateDoesNotExist, Template
|
||||
import django.template.loader
|
||||
from rest_framework.compat import patterns, url
|
||||
from rest_framework.decorators import api_view, renderer_classes
|
||||
from rest_framework.renderers import TemplateHTMLRenderer
|
||||
from rest_framework.response import Response
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django.conf.urls import patterns, url
|
||||
from django.db import models
|
||||
from django.test import TestCase
|
||||
from rest_framework import serializers
|
||||
from rest_framework.compat import patterns, url
|
||||
|
||||
|
||||
def dummy_view(request, pk):
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from django.utils import simplejson as json
|
||||
from rest_framework import generics, status, serializers
|
||||
from rest_framework.compat import patterns, url
|
||||
from rest_framework.tests.models import Anchor, BasicModel, ManyToManyModel, BlogPost, BlogPostComment, Album, Photo, OptionalRelationModel
|
||||
|
||||
factory = RequestFactory()
|
||||
|
|
|
@ -51,6 +51,11 @@ class RESTFrameworkModel(models.Model):
|
|||
abstract = True
|
||||
|
||||
|
||||
class HasPositiveIntegerAsChoice(RESTFrameworkModel):
|
||||
some_choices = ((1, 'A'), (2, 'B'), (3, 'C'))
|
||||
some_integer = models.PositiveIntegerField(choices=some_choices)
|
||||
|
||||
|
||||
class Anchor(RESTFrameworkModel):
|
||||
text = models.CharField(max_length=100, default='anchor')
|
||||
|
||||
|
@ -160,7 +165,7 @@ class Photo(RESTFrameworkModel):
|
|||
|
||||
# Model for issue #324
|
||||
class BlankFieldModel(RESTFrameworkModel):
|
||||
title = models.CharField(max_length=100, blank=True, null=True)
|
||||
title = models.CharField(max_length=100, blank=True, null=False)
|
||||
|
||||
|
||||
# Model for issue #380
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import pickle
|
||||
import re
|
||||
|
||||
from django.conf.urls.defaults import patterns, url, include
|
||||
from django.core.cache import cache
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from rest_framework import status, permissions
|
||||
from rest_framework.compat import yaml
|
||||
from rest_framework.compat import yaml, patterns, url, include
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer, \
|
||||
|
@ -444,19 +443,19 @@ class CacheRenderTest(TestCase):
|
|||
return
|
||||
if state == None:
|
||||
return
|
||||
if isinstance(state,tuple):
|
||||
if not isinstance(state[0],dict):
|
||||
state=state[1]
|
||||
if isinstance(state, tuple):
|
||||
if not isinstance(state[0], dict):
|
||||
state = state[1]
|
||||
else:
|
||||
state=state[0].update(state[1])
|
||||
state = state[0].update(state[1])
|
||||
result = {}
|
||||
for i in state:
|
||||
try:
|
||||
pickle.dumps(state[i],protocol=2)
|
||||
pickle.dumps(state[i], protocol=2)
|
||||
except pickle.PicklingError:
|
||||
if not state[i] in seen:
|
||||
seen.append(state[i])
|
||||
result[i] = cls._get_pickling_errors(state[i],seen)
|
||||
result[i] = cls._get_pickling_errors(state[i], seen)
|
||||
return result
|
||||
|
||||
def http_resp(self, http_method, url):
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
"""
|
||||
Tests for content parsing, and form-overloaded content parsing.
|
||||
"""
|
||||
from django.conf.urls.defaults import patterns
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from django.test import TestCase, Client
|
||||
from django.test.client import RequestFactory
|
||||
from django.utils import simplejson as json
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from django.test.client import RequestFactory
|
||||
from rest_framework.compat import patterns
|
||||
from rest_framework.parsers import (
|
||||
BaseParser,
|
||||
FormParser,
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import unittest
|
||||
|
||||
from django.conf.urls.defaults import patterns, url, include
|
||||
from django.test import TestCase
|
||||
|
||||
from rest_framework.compat import patterns, url, include
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from rest_framework.compat import patterns, url
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
factory = RequestFactory()
|
||||
|
|
|
@ -2,7 +2,7 @@ import datetime
|
|||
import pickle
|
||||
from django.test import TestCase
|
||||
from rest_framework import serializers
|
||||
from rest_framework.tests.models import (Album, ActionItem, Anchor, BasicModel,
|
||||
from rest_framework.tests.models import (HasPositiveIntegerAsChoice, Album, ActionItem, Anchor, BasicModel,
|
||||
BlankFieldModel, BlogPost, Book, CallableDefaultValueModel, DefaultValueModel,
|
||||
ManyToManyModel, Person, ReadOnlyManyToManyModel, Photo)
|
||||
|
||||
|
@ -69,6 +69,11 @@ class AlbumsSerializer(serializers.ModelSerializer):
|
|||
model = Album
|
||||
fields = ['title'] # lists are also valid options
|
||||
|
||||
class PositiveIntegerAsChoiceSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = HasPositiveIntegerAsChoice
|
||||
fields = ['some_integer']
|
||||
|
||||
|
||||
class BasicTests(TestCase):
|
||||
def setUp(self):
|
||||
|
@ -285,6 +290,12 @@ class ValidationTests(TestCase):
|
|||
self.assertEquals(serializer.errors, {'info': [u'Ensure this value has at most 12 characters (it has 13).']})
|
||||
|
||||
|
||||
class PositiveIntegerAsChoiceTests(TestCase):
|
||||
def test_positive_integer_in_json_is_correctly_parsed(self):
|
||||
data = {'some_integer':1}
|
||||
serializer = PositiveIntegerAsChoiceSerializer(data=data)
|
||||
self.assertEquals(serializer.is_valid(), True)
|
||||
|
||||
class ModelValidationTests(TestCase):
|
||||
def test_validate_unique(self):
|
||||
"""
|
||||
|
@ -720,6 +731,10 @@ class BlankFieldTests(TestCase):
|
|||
serializer = self.model_serializer_class(data=self.data)
|
||||
self.assertEquals(serializer.is_valid(), True)
|
||||
|
||||
def test_create_model_null_field(self):
|
||||
serializer = self.model_serializer_class(data={'title': None})
|
||||
self.assertEquals(serializer.is_valid(), True)
|
||||
|
||||
def test_create_not_blank_field(self):
|
||||
"""
|
||||
Test to ensure blank data in a field not marked as blank=True
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.test import TestCase
|
|||
|
||||
NO_SETTING = ('!', None)
|
||||
|
||||
|
||||
class TestSettingsManager(object):
|
||||
"""
|
||||
A class which can modify some Django settings temporarily for a
|
||||
|
@ -19,7 +20,7 @@ class TestSettingsManager(object):
|
|||
self._original_settings = {}
|
||||
|
||||
def set(self, **kwargs):
|
||||
for k,v in kwargs.iteritems():
|
||||
for k, v in kwargs.iteritems():
|
||||
self._original_settings.setdefault(k, getattr(settings, k,
|
||||
NO_SETTING))
|
||||
setattr(settings, k, v)
|
||||
|
@ -31,7 +32,7 @@ class TestSettingsManager(object):
|
|||
call_command('syncdb', verbosity=0)
|
||||
|
||||
def revert(self):
|
||||
for k,v in self._original_settings.iteritems():
|
||||
for k, v in self._original_settings.iteritems():
|
||||
if v == NO_SETTING:
|
||||
delattr(settings, k)
|
||||
else:
|
||||
|
@ -57,6 +58,7 @@ class SettingsTestCase(TestCase):
|
|||
def tearDown(self):
|
||||
self.settings_manager.revert()
|
||||
|
||||
|
||||
class TestModelsTestCase(SettingsTestCase):
|
||||
def setUp(self, *args, **kwargs):
|
||||
installed_apps = tuple(settings.INSTALLED_APPS) + ('rest_framework.tests',)
|
||||
|
|
|
@ -12,7 +12,7 @@ your authentication settings include `SessionAuthentication`.
|
|||
url(r'^auth', include('rest_framework.urls', namespace='rest_framework'))
|
||||
)
|
||||
"""
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
from rest_framework.compat import patterns, url
|
||||
|
||||
|
||||
template_name = {'template_name': 'rest_framework/login.html'}
|
||||
|
|
8
tox.ini
8
tox.ini
|
@ -12,12 +12,12 @@ deps = https://github.com/django/django/zipball/master
|
|||
|
||||
[testenv:py2.7-django1.4]
|
||||
basepython = python2.7
|
||||
deps = django==1.4.1
|
||||
deps = django==1.4.3
|
||||
django-filter==0.5.4
|
||||
|
||||
[testenv:py2.7-django1.3]
|
||||
basepython = python2.7
|
||||
deps = django==1.3.3
|
||||
deps = django==1.3.5
|
||||
django-filter==0.5.4
|
||||
|
||||
[testenv:py2.6-django1.5]
|
||||
|
@ -27,10 +27,10 @@ deps = https://github.com/django/django/zipball/master
|
|||
|
||||
[testenv:py2.6-django1.4]
|
||||
basepython = python2.6
|
||||
deps = django==1.4.1
|
||||
deps = django==1.4.3
|
||||
django-filter==0.5.4
|
||||
|
||||
[testenv:py2.6-django1.3]
|
||||
basepython = python2.6
|
||||
deps = django==1.3.3
|
||||
deps = django==1.3.5
|
||||
django-filter==0.5.4
|
||||
|
|
Loading…
Reference in New Issue
Block a user