mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 17:47:04 +03:00
Merge branch 'master' of https://github.com/tomchristie/django-rest-framework
This commit is contained in:
commit
1fd83adb9c
|
@ -195,9 +195,9 @@ For more details on using filter sets see the [django-filter documentation][djan
|
|||
|
||||
## SearchFilter
|
||||
|
||||
The `SearchFilterBackend` class supports simple single query parameter based searching, and is based on the [Django admin's search functionality][search-django-admin].
|
||||
The `SearchFilter` class supports simple single query parameter based searching, and is based on the [Django admin's search functionality][search-django-admin].
|
||||
|
||||
The `SearchFilterBackend` class will only be applied if the view has a `search_fields` attribute set. The `search_fields` attribute should be a list of names of text type fields on the model, such as `CharField` or `TextField`.
|
||||
The `SearchFilter` class will only be applied if the view has a `search_fields` attribute set. The `search_fields` attribute should be a list of names of text type fields on the model, such as `CharField` or `TextField`.
|
||||
|
||||
class UserListView(generics.ListAPIView):
|
||||
queryset = User.objects.all()
|
||||
|
|
|
@ -169,6 +169,7 @@ The following people have helped make REST framework great.
|
|||
* Edmond Wong - [edmondwong]
|
||||
* Ben Reilly - [bwreilly]
|
||||
* Tai Lee - [mrmachine]
|
||||
* Markus Kaiserswerth - [mkai]
|
||||
|
||||
Many thanks to everyone who's contributed to the project.
|
||||
|
||||
|
@ -374,3 +375,4 @@ You can also contact [@_tomchristie][twitter] directly on twitter.
|
|||
[edmondwong]: https://github.com/edmondwong
|
||||
[bwreilly]: https://github.com/bwreilly
|
||||
[mrmachine]: https://github.com/mrmachine
|
||||
[mkai]: https://github.com/mkai
|
||||
|
|
|
@ -147,7 +147,7 @@ Similarly, we can control the format of the request that we send, using the `Con
|
|||
# POST using form data
|
||||
curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 123"
|
||||
|
||||
{"id": 3, "title": "", "code": "123", "linenos": false, "language": "python", "style": "friendly"}
|
||||
{"id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly"}
|
||||
|
||||
# POST using JSON
|
||||
curl -X POST http://127.0.0.1:8000/snippets/ -d '{"code": "print 456"}' -H "Content-Type: application/json"
|
||||
|
|
|
@ -85,7 +85,7 @@ Right, we'd better write some views then. Open `quickstart/views.py` and get ty
|
|||
queryset = Group.objects.all()
|
||||
serializer_class = GroupSerializer
|
||||
|
||||
Rather that write multiple views we're grouping together all the common behavior into classes called `ViewSets`.
|
||||
Rather than write multiple views we're grouping together all the common behavior into classes called `ViewSets`.
|
||||
|
||||
We can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise.
|
||||
|
||||
|
|
|
@ -80,6 +80,14 @@ except ImportError:
|
|||
Image = None
|
||||
|
||||
|
||||
def get_model_name(model_cls):
|
||||
try:
|
||||
return model_cls._meta.model_name
|
||||
except AttributeError:
|
||||
# < 1.6 used module_name instead of model_name
|
||||
return model_cls._meta.module_name
|
||||
|
||||
|
||||
def get_concrete_model(model_cls):
|
||||
try:
|
||||
return model_cls._meta.concrete_model
|
||||
|
|
|
@ -4,7 +4,7 @@ returned by list views.
|
|||
"""
|
||||
from __future__ import unicode_literals
|
||||
from django.db import models
|
||||
from rest_framework.compat import django_filters, six, guardian
|
||||
from rest_framework.compat import django_filters, six, guardian, get_model_name
|
||||
from functools import reduce
|
||||
import operator
|
||||
|
||||
|
@ -158,7 +158,7 @@ class DjangoObjectPermissionsFilter(BaseFilterBackend):
|
|||
model_cls = queryset.model
|
||||
kwargs = {
|
||||
'app_label': model_cls._meta.app_label,
|
||||
'model_name': model_cls._meta.module_name
|
||||
'model_name': get_model_name(model_cls)
|
||||
}
|
||||
permission = self.perm_format % kwargs
|
||||
return guardian.shortcuts.get_objects_for_user(user, permission, queryset)
|
||||
|
|
|
@ -8,7 +8,8 @@ import warnings
|
|||
SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
|
||||
|
||||
from django.http import Http404
|
||||
from rest_framework.compat import oauth2_provider_scope, oauth2_constants
|
||||
from rest_framework.compat import (get_model_name, oauth2_provider_scope,
|
||||
oauth2_constants)
|
||||
|
||||
|
||||
class BasePermission(object):
|
||||
|
@ -116,7 +117,7 @@ class DjangoModelPermissions(BasePermission):
|
|||
"""
|
||||
kwargs = {
|
||||
'app_label': model_cls._meta.app_label,
|
||||
'model_name': model_cls._meta.module_name
|
||||
'model_name': get_model_name(model_cls)
|
||||
}
|
||||
return [perm % kwargs for perm in self.perms_map[method]]
|
||||
|
||||
|
@ -177,7 +178,7 @@ class DjangoObjectPermissions(DjangoModelPermissions):
|
|||
def get_required_object_permissions(self, method, model_cls):
|
||||
kwargs = {
|
||||
'app_label': model_cls._meta.app_label,
|
||||
'model_name': model_cls._meta.module_name
|
||||
'model_name': get_model_name(model_cls)
|
||||
}
|
||||
return [perm % kwargs for perm in self.perms_map[method]]
|
||||
|
||||
|
|
|
@ -518,6 +518,9 @@ class BaseSerializer(WritableField):
|
|||
"""
|
||||
Save the deserialized object and return it.
|
||||
"""
|
||||
# Clear cached _data, which may be invalidated by `save()`
|
||||
self._data = None
|
||||
|
||||
if isinstance(self.object, list):
|
||||
[self.save_object(item, **kwargs) for item in self.object]
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.db import models
|
|||
from django.test import TestCase
|
||||
from django.utils import unittest
|
||||
from rest_framework import generics, status, permissions, authentication, HTTP_HEADER_ENCODING
|
||||
from rest_framework.compat import guardian
|
||||
from rest_framework.compat import guardian, get_model_name
|
||||
from rest_framework.filters import DjangoObjectPermissionsFilter
|
||||
from rest_framework.test import APIRequestFactory
|
||||
from rest_framework.tests.models import BasicModel
|
||||
|
@ -202,7 +202,7 @@ class ObjectPermissionsIntegrationTests(TestCase):
|
|||
|
||||
# give everyone model level permissions, as we are not testing those
|
||||
everyone = Group.objects.create(name='everyone')
|
||||
model_name = BasicPermModel._meta.module_name
|
||||
model_name = get_model_name(BasicPermModel)
|
||||
app_label = BasicPermModel._meta.app_label
|
||||
f = '{0}_{1}'.format
|
||||
perms = {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
from django.db import models
|
||||
from django.db.models.fields import BLANK_CHOICE_DASH
|
||||
|
@ -136,6 +137,7 @@ class BasicTests(TestCase):
|
|||
'Happy new year!',
|
||||
datetime.datetime(2012, 1, 1)
|
||||
)
|
||||
self.actionitem = ActionItem(title='Some to do item',)
|
||||
self.data = {
|
||||
'email': 'tom@example.com',
|
||||
'content': 'Happy new year!',
|
||||
|
@ -264,6 +266,20 @@ class BasicTests(TestCase):
|
|||
"""
|
||||
self.assertRaises(AssertionError, PersonSerializerInvalidReadOnly, [])
|
||||
|
||||
def test_serializer_data_is_cleared_on_save(self):
|
||||
"""
|
||||
Check _data attribute is cleared on `save()`
|
||||
|
||||
Regression test for #1116
|
||||
— id field is not populated if `data` is accessed prior to `save()`
|
||||
"""
|
||||
serializer = ActionItemSerializer(self.actionitem)
|
||||
self.assertIsNone(serializer.data.get('id',None), 'New instance. `id` should not be set.')
|
||||
serializer.save()
|
||||
self.assertIsNotNone(serializer.data.get('id',None), 'Model is saved. `id` should be set.')
|
||||
|
||||
|
||||
|
||||
|
||||
class DictStyleSerializer(serializers.Serializer):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue
Block a user