Web APIs for Django. 🎸

Overview

Django REST framework

build-status-image coverage-status-image pypi-version

Awesome web-browsable Web APIs.

Full documentation for the project is available at https://www.django-rest-framework.org/.


Funding

REST framework is a collaboratively funded project. If you use REST framework commercially we strongly encourage you to invest in its continued development by signing up for a paid plan.

The initial aim is to provide a single full-time position on REST framework. Every single sign-up makes a significant impact towards making that possible.

Many thanks to all our wonderful sponsors, and in particular to our premium backers, Sentry, Stream, Rollbar, ESG, Retool, and bit.io.


Overview

Django REST framework is a powerful and flexible toolkit for building Web APIs.

Some reasons you might want to use REST framework:

There is a live example API for testing purposes, available here.

Below: Screenshot from the browsable API

Screenshot


Requirements

  • Python (3.5, 3.6, 3.7, 3.8, 3.9)
  • Django (2.2, 3.0, 3.1)

We highly recommend and only officially support the latest patch release of each Python and Django series.

Installation

Install using pip...

pip install djangorestframework

Add 'rest_framework' to your INSTALLED_APPS setting.

INSTALLED_APPS = [
    ...
    'rest_framework',
]

Example

Let's take a look at a quick example of using REST framework to build a simple model-backed API for accessing users and groups.

Startup up a new project like so...

pip install django
pip install djangorestframework
django-admin startproject example .
./manage.py migrate
./manage.py createsuperuser

Now edit the example/urls.py module in your project:

from django.urls import path, include
from django.contrib.auth.models import User
from rest_framework import serializers, viewsets, routers

# Serializers define the API representation.
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ['url', 'username', 'email', 'is_staff']


# ViewSets define the view behavior.
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer


# Routers provide a way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)


# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    path('', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

We'd also like to configure a couple of settings for our API.

Add the following to your settings.py module:

INSTALLED_APPS = [
    ...  # Make sure to include the default installed apps here.
    'rest_framework',
]

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ]
}

That's it, we're done!

./manage.py runserver

You can now open the API in your browser at http://127.0.0.1:8000/, and view your new 'users' API. If you use the Login control in the top right corner you'll also be able to add, create and delete users from the system.

You can also interact with the API using command line tools such as curl. For example, to list the users endpoint:

$ curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
[
    {
        "url": "http://127.0.0.1:8000/users/1/",
        "username": "admin",
        "email": "[email protected]",
        "is_staff": true,
    }
]

Or to create a new user:

$ curl -X POST -d username=new -d [email protected] -d is_staff=false -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
{
    "url": "http://127.0.0.1:8000/users/2/",
    "username": "new",
    "email": "[email protected]",
    "is_staff": false,
}

Documentation & Support

Full documentation for the project is available at https://www.django-rest-framework.org/.

For questions and support, use the REST framework discussion group, or #restframework on freenode IRC.

You may also want to follow the author on Twitter.

Security

Please see the security policy.

Issues
  • PUT calls don't fully

    PUT calls don't fully "replace the state of the target resource"

    EDIT: For the current status of the issue, skip to https://github.com/encode/django-rest-framework/issues/4231#issuecomment-332935943

    ===

    I'm having an issue implementing an Optimistic Concurrency library on an application that uses DRF to interact with the database. I'm trying to:

    • Confirm that the behavior I'm seeing is attributable to DRF
    • Confirm that this is the intended behavior
    • Determine if there's any practical way to overcome this behavior

    I recently added optimistic concurrency to my Django application. To save you the Wiki lookup:

    • Every model has a version field
    • When an editor edits an object, they get the version of the object they're editing
    • When the editor saves the object, the included version number is compared to the database
    • If the versions match, the editor updated the latest document and the save goes through
    • If the versions don't match, we assume a "conflicting" edit was submitted between the time the editor loaded and saved so we reject the edit
    • If the version is missing, we cannot do testing and should reject the edit

    I had a legacy UI talking through DRF. The legacy UI did not handle version numbers. I expected this to cause concurrency errors, but it did not. If I understand the discussion in #3648 correctly:

    • DRF merges the PUT with the existing record. This causes a missing version ID to be filled with the current database ID
    • Since this always provides a match, omitting this variable will always break an optimistic concurrency system that communicates across DRF
    • ~There are no easy options (like making the field "required") to ensure the data is submitted every time.~ (edit: you can workaround the issue by making it required as demonstrated in this comment)

    Steps to reproduce

    1. Setup an Optimistic Concurrency field on a model
    2. Create a new instance and update several times (to ensure you no longer have a default version number)
    3. Submit an update (PUT) through DRF excluding the version ID

    Expected behavior

    The missing version ID should not match the database and cause a concurrency issue.

    Actual behavior

    The missing version ID is filled by DRF with the current ID so the concurrency check passes.

    Enhancement 
    opened by claytondaley 68
  • Introduce error code for validation errors.

    Introduce error code for validation errors.

    This patch is meant to fix #3111, regarding comments made to #3137 and #3169.

    The ValidationError will now contain a code attribute.

    Before this patch, ValidationError.detail only contained a dict with values equal to a list of string error messages or directly a list containing string error messages.

    Now, the string error messages are replaced with ValidationError.

    This means that, depending on the case, you will not only get a string back but a full object containing both the error message and the error code, respectively ValidationError.detail and ValidationError.code.

    It is important to note that the code attribute is not relevant when the ValidationError represents a combination of errors and hence is None in such cases.

    The main benefit of this change is that the error message and error code are now accessible in the custom exception handler and can be used to format the error response.

    A custom exception handler example is available in the TestValidationErrorWithCode test.

    Regarding the other discussion:

    • This PR doesn't require any new settings
    • The build_error method was dropped
    • The build_error_from_django_validation_error has been kept because this is the only way to "convert" a regular DjangoValidationError to a djrf ValidationError.

    @tomchristie @jpadilla @qsorix: if you don't mind giving this a look ;-)

    Enhancement 
    opened by johnraz 63
  • Removing _closable_objects for pickling breaks response processing

    Removing _closable_objects for pickling breaks response processing

    Here _closable_objects was added to rendering_attrs https://github.com/tomchristie/django-rest-framework/commit/59d0a0387d907260ef8f91bbbca618831abd75a3#diff-21a03cd19b8422c334c33ec8da66e9c8R21

    Every rendering attribute is deleted in __getstate__ method https://github.com/django/django/blob/1.7/django/template/response.py#L45

    But _closable_objects is used in base response handler: https://github.com/django/django/blob/1.7/django/core/handlers/base.py#L210

    That's why after processing response from cache i get error like this:

    Traceback (most recent call last):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/handlers.py", line 85, in run
        self.result = application(self.environ, self.start_response)
      File "/Users/web-chib/drf-ussie/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 64, in __call__
        return self.application(environ, start_response)
      File "/Users/web-chib/drf-ussie/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 187, in __call__
        response = self.get_response(request)
      File "/Users/web-chib/drf-ussie/lib/python2.7/site-packages/django/core/handlers/base.py", line 211, in get_response
        response._closable_objects.append(request)
    AttributeError: 'Response' object has no attribute '_closable_objects'
    

    I don't know, should i recreate this attribute by hand, or that's DRF error?

    Bug 
    opened by chibisov 61
  • Schema generation doesn't support response schemas

    Schema generation doesn't support response schemas

    This is a useful feature, at least for swagger, and the way things are right now it cannot be implemented from outside of DRF, since the Link object doesn't contain the schema for the response.

    While the fields can be implied from the input fields, for read only endpoints this is not an option.

    Enhancement Schema Generation 
    opened by gcbirzan 57
  • Migrate documentation to MkDocs proper

    Migrate documentation to MkDocs proper

    This is still a bit of a work in progress, but throwing it up so people can see and provide feedback if they want.

    Documentation 
    opened by d0ugal 55
  • Request.data empty when multipart/form-data POSTed

    Request.data empty when multipart/form-data POSTed

    Django==1.9.2 djangorestframework==3.3.2

    This is essentially a repost of #3814. There is already some research and discussion attached to that issue that I will not rehash, but the author closed out the item once a workaround was found.

    Is that workaround the long term solution? Is the answer to never touch the Django Request before DRF has a chance to do its thing? This can be difficult to control in projects with third party middleware.

    The issue seems to be that, when POSTing data, Django is exhausting the underlying request stream if the WSGIRequest is accessed prior to initialize_request in the DRF View dispatcher. PUTs seem to be unaffected.

    A totally contrived example that demonstrates the issue. First example, presuming no middleware Request meddling...

    class TestView(APIView):
    
        def post(self, request, *args, **kwargs):
            # request.data, .FILES, and .POST are populated
            # request._request.FILES and .POST are empty
            return Response()
    
        def put(self, request, *args, **kwargs):
            # request.data, .FILES, and .POST are populated
            # request._request.FILES and .POST are empty
            return Response()
    

    Second example, forcibly evaluating the Django request before dispatching.

    class TestView(APIView):
    
        def dispatch(self, request, *args, **kwargs):
            p = request.POST  # Force evaluation of the Django request
            return super().dispatch(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            # request.data, .FILES, and .POST are empty
            # request._request.FILES and .POST are populated
            return Response()
    
        def put(self, request, *args, **kwargs):
            # request.data, .FILES, and .POST are populated
            # request._request.FILES and .POST are empty
            return Response()
    

    Cheers!

    Needs confirmation 
    opened by CaffeineFueled 55
  • Support

    Support "extra actions" for routing in the HTML forms for the browsable API

    Add support for creating HTML forms for the browsable API for "extra actions" for routing.

    For example using the example from the linked page:

        @detail_route(methods=['post'])
        def set_password(self, request, pk=None):
    

    creating a form for calling set_password. Likely this would require additional arguments passed to the detail_route decorator (such as the serializer used, PasswordSerializer).

    See: https://groups.google.com/forum/#!topic/django-rest-framework/e75osh1Wcyg

    Enhancement 
    opened by cancan101 40
  • Nested Routers: Allow nested URLs for resources, like /carts/{nested_1_pk}/itens/{pk}

    Nested Routers: Allow nested URLs for resources, like /carts/{nested_1_pk}/itens/{pk}

    I wrote a PoC NestedSimpleRouter, that nests its URLs into some other router routes. Usage:

    # urls.py
    (...)
    router = routers.SimpleRouter()
    router.register(r'carts', CartViewSet)
    
    carts_router = routers.NestedSimpleRouter(router, r'carts')
    carts_router.register(r'itens', ItensViewSet)
    
    url_patterns = patterns('',
        url(r'^', include(router.urls)),
        url(r'^', include(carts_router.urls)),
    )
    

    This creates the following URLs:

    ^carts/$ [name='cart-list']
    ^carts/(?P<pk>[^/]+)/$ [name='cart-detail']
    ^carts/(?P<nested_1_pk>[^/]+)/itens/$ [name='item-list']
    ^carts/(?P<nested_1_pk>[^/]+)/itens/(?P<pk>[^/]+)/$ [name='item-detail']
    

    And is intended to be used like:

    # views.py
    class ItemViewSet(viewsets.ViewSet):
        model = Item
    
        def list(self, request, nested_1_pk=None):
            cart = Cart.objects.get(pk=nested_1_pk)
            return Response([])
    
        def retrieve(self, request, pk=None, nested_1_pk=None):
            (...)
    

    The nested_1_pk is automatic, and should grow to nested_{n}_{lookup_field} as you nest Nested routers, but this will need more work into SimpleRouter.get_lookup_regex() to do it ( and I need some sleep now :P )

    It works very well, but have no tests yet.

    What you think?

    Enhancement 
    opened by alanjds 37
  • Serializers many to many field not reflecting edits made in PUT/PATCH if prefetch_related used

    Serializers many to many field not reflecting edits made in PUT/PATCH if prefetch_related used

    If you use a viewset with a queryset using prefetch_related, any update to those prefetched many to many fields is not reflected in the response to the client, although the changes have been saved to the database.

    See below code for very simple example:

    from django.conf.urls import patterns, include, url
    from django.contrib import admin
    from django.contrib.auth.models import User
    from rest_framework import serializers, viewsets, routers
    
    
    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ('id', 'username', 'email', 'groups')
    
    
    class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all().prefetch_related('groups')
        serializer_class = UserSerializer
    
    
    router = routers.DefaultRouter()
    router.register(r'users', UserViewSet)
    
    urlpatterns = patterns('',
        url(r'^', include(router.urls)),
        url(r'^api-auth/', include('rest_framework.urls',
                                   namespace='rest_framework')),
        url(r'^admin/', include(admin.site.urls)),
    )
    

    With the above code, assume there is an existing user with 2 groups assigned:

    {
        "id": 1, 
        "username": "chris", 
        "email": "[email protected]", 
        "groups": [
            1,
            2
        ]
    }
    

    Submitting a PUT to /users/1/ changing groups to [1], the response will still show groups as [1, 2], but if you then did a GET request for /users/1/ you would see the reflected changes.

    You can see this behaviour using the browseable api also.

    Removing prefetch_related from the queryset restores normal behaviour and edits are again reflected in the response.

    This example is very trivial, but if people are using prefetch_related to try and optimise their database queries they may encounter this issue.

    Bug 
    opened by chrismcband 36
  • Views are using a subclass or HttpRequest

    Views are using a subclass or HttpRequest

    The new custom request takes care of ".DATA", ".FILES", overloaded HTTP method, content type and content.

    • tests
    • some doc.
    opened by sebpiq 35
  • Refa(authentication): improve code quality

    Refa(authentication): improve code quality

    I improved the quality of authentication code and removed extra lines

    opened by fariddarabi 0
  • Docs: Fix minor issue with permissions table

    Docs: Fix minor issue with permissions table

    I might just be misunderstanding something (always a strong possibility!), but it seems to me that the table on the Permissions page is slightly inaccurate.

    For permission_classes, wouldn't it have global-level permissions for list actions (rather than no permission control, as is currently listed)?

    opened by matthewpull 0
  • BrowsableAPIRenderer.get_raw_data_form should exclude read-only fields, too

    BrowsableAPIRenderer.get_raw_data_form should exclude read-only fields, too

    renderers.py:

        # strip HiddenField from output
        data = serializer.data.copy()
        for name, field in serializer.fields.items():
            if isinstance(field, serializers.HiddenField):  # <--- or field.read_only
                data.pop(name, None)
    
    
    opened by pbav 0
  • Fixed missing

    Fixed missing "fields" meta argument in docs

    In "Specifying fields explicitly" https://github.com/encode/django-rest-framework/blob/master/docs/api-guide/serializers.md#specifying-fields-explicitly paragraph from the docs, the code example provided was missing the fields meta argument, which is mandatory from 3.3.0. The assertion error was: Creating a ModelSerializer without either the 'fields' attribute or the 'exclude' attribute has been deprecated since 3.3.0, and is now disallowed. Add an explicit fields = '__all__' to the CalendarTaskSerializer serializer.

    opened by Guilouf 0
  • License type is not set under project

    License type is not set under project

    Hi team, can use this project with custom license without knowing in which category it fall under for business usage. Can you select appropriate license type for this project to be able to see if it is under Mit, GPL etc..

    At the moment it is not clear if it can be used for commercial purpose.

    https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository#disclaimer

    opened by rimvislt 0
  • Warn when extra_field_kwargs includes fields explicitly declared related to #3460)

    Warn when extra_field_kwargs includes fields explicitly declared related to #3460)

    This PR adds an invariant check via a loud assert (as suggested here) to help with issue https://github.com/encode/django-rest-framework/issues/3460.

    The goal is to notify people when they include fields in extra_kwargs (either directly or, more worryingly because of security, via read_only_fields). For example, I've seen this time and time again in production code:

    class MySerializer(ModelSerializer):
        my_sensitive_field = ...
        ...
        class Meta:
            fields = ('my_sensitive_field', ...)
            read_only_fields = ('my_sensitive_field', )
    

    I believe most people assume that my_sensitive_field is now readonly, without knowing that extra_kwargs, and, hence, read_only_fields, only apply to fields not explicitly declared.

    opened by Jorl17 2
  • Docs: IsAdmin permissions changed to IsAdminUser

    Docs: IsAdmin permissions changed to IsAdminUser

    Documentation change to keep up with the code permission changes.

    opened by Back2Basics 0
  • Docs: remove old-style `super` call

    Docs: remove old-style `super` call

    Description

    A small tweak for the serializer docs

    opened by TheMC47 1
  • validated_data is returning empty OrderedDict for nested fields

    validated_data is returning empty OrderedDict for nested fields

    I've researched the issue on SO, and the only cause for this happening I've found is that the request is sent as Form-data and not Json, but I've checked that response.content_type equals application/json - so this shouldn't be the issue here.

    This is what my validated_data looks like (note that 3 of the fields only contain an empty OrderedDict):

    
    {'author': OrderedDict(),
     'disclosed_at': datetime.datetime(2021, 10, 19, 12, 0, tzinfo=<DstTzInfo 'Europe/Stockholm' CEST+2:00:00 DST>),
     'event_date': datetime.date(2021, 10, 20),
     'event_type': OrderedDict(),
     'subject_companies': [OrderedDict()]}
    
    

    This is what request.data looks like (where you can see that all fields are there, and having the fields that each serializer have specified, provided below this paragraph):

    {'event_type': {'pk': 1}, 'author': {'pk': 1}, 'event_date': '2021-10-20', 'disclosed_at': '2021-10-19 12:00:00', 'subject_companies': [{'pk': 1}]}

    This is where I'm sending the request from (test.py):

    
      def test_authenticated_creating_event_for_own_organisation(self):
            view = NewsEventList.as_view()
            url = reverse('news_event_list', kwargs={'pk': self.organisation.pk})
            request = self.client.post(url, data=json.dumps(self.payload_event), content_type='application/json')
            force_authenticate(request, user=self.user)
            response = view(request, pk=self.organisation.pk)
            
            json_data = json.dumps(response.data, indent=4)
            json_ = (json.loads(json_data))  
    
            self.assertEqual(response.status_code, 201, 'Should return 201 - Created')
            return response
    

    The view

    
    class NewsEventList(generics.ListCreateAPIView):
    permission_classes = (IsAuthenticatedAndOfSameOrganisationEvents,)
    serializer_class = NewsEventSerializer
    
    def get_queryset(self):
        org_pk = self.kwargs.get('pk', None)
        try:
            org_obj = Organisation.objects.get(pk=org_pk)
        except Organisation.DoesNotExist:
            return ValidationError('Organisation does not exist')
    
        news_events = NewsEvent.objects.filter(author=org_obj)
        return news_events
    

    Serializers

    
    class OrganisationNameSerializer(ModelSerializer):
    
        class Meta:
            model = Organisation
            fields = ['pk']
    
    
    class EventTypeSerializer(ModelSerializer):
    
        class Meta:
            model = EventType
            fields = ['pk']
    
    class HeadlineSerializer(ModelSerializer):
    
        class Meta:
            model = EventHeadline
            fields = ['news_event', 'language', 'headline']
    
    class NewsEventSerializer(ModelSerializer):
        event_type = EventTypeSerializer()
        author = OrganisationNameSerializer()
        subject_companies = OrganisationNameSerializer(many=True)
    
        class Meta:
            model = NewsEvent
            fields = ['pk', 'event_type', 'author', 'event_date', 'event_time', 'disclosed_at', 'subject_companies', 'created_at', 'updated_at']
    
        def create(self, validated_data):
    
            # Get PK for organisation from URL
            org_pk = self.context.get('request').parser_context.get('kwargs', {}).get('pk', {})
            org_obj = Organisation.objects.get(pk=org_pk)
    
            print(self.context.get('request').data)
            pprint(validated_data)
    
    

    Also for reference I printed the serializer.data for an already existing instance of a NewsEvent:

    news_event_test = NewsEvent.objects.all()[0]
    serializer = NewsEventSerializer(news_event_test)
    print(serializer.data)
        
    {'pk': 1, 'event_type': OrderedDict([('pk', 1)]), 'author': OrderedDict([('pk', 1)]), 'event_date': None, 'event_time': None, 'disclosed_at': None, 'subject_companies': [OrderedDict([('pk', 1)])], 'created_at': '2021-10-25T09:32:41.562428+02:00', 'updated_at': '2021-10-25T09:32:41.562487+02:00'}```
    
    I've also tried doing a "pop" of each of the fields from the validated_object, but only the ones that don't is an empty OrderedDict work, such as disclosed_at, but if I try to do:
    
    event_type = validated_data.pop('event_type')
    I get:
    
    `KeyError: "Got KeyError when attempting to get a value for field `event_type` on serializer `NewsEventSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'event_type'."`
    opened by allinws 2
  • docs(tutorial: 5): improve wording (#8218)

    docs(tutorial: 5): improve wording (#8218)

    Related Issue

    • https://github.com/encode/django-rest-framework/issues/8218

    Description

    On https://github.com/encode/django-rest-framework/blob/master/docs/tutorial/5-relationships-and-hyperlinked-apis.md#hyperlinking-our-api,

    Change wording

    • OLD the more challenging aspects of Web API design
    • NEW the most challenging aspects of Web API design
    opened by nat236919 0
Releases(3.12.4)
  • 3.9.3(Apr 29, 2019)

    This is the last Django REST Framework release that will support Python 2. Be sure to upgrade to Python 3 before upgrading to Django REST Framework 3.10.

    • Adjusted the compat check for django-guardian to allow the last guardian version (v1.4.9) compatible with Python 2. #6613
    Source code(tar.gz)
    Source code(zip)
  • 3.9.2(Mar 3, 2019)

  • 3.9.1(Feb 28, 2019)

  • 3.9.0(Feb 28, 2019)

    Release announcement: https://www.django-rest-framework.org/community/3.9-announcement/

    Change Notes: https://www.django-rest-framework.org/community/release-notes/#39x-series

    Source code(tar.gz)
    Source code(zip)
  • 3.8.2(Apr 6, 2018)

    Point release for 3.8.x series

    • Fix read_only + default unique_together validation. #5922
    • authtoken.views import coreapi from rest_framework.compat, not directly. #5921
    • Docs: Add missing argument 'detail' to Route #5920
    Source code(tar.gz)
    Source code(zip)
  • 3.8.1(Apr 4, 2018)

    • Use old url_name behavior in route decorators #5915

      For list_route and detail_route maintain the old behavior of url_name, basing it on the url_path instead of the function name.

    Source code(tar.gz)
    Source code(zip)
  • 3.8.0(Apr 3, 2018)

    • Release Announcement

    • 3.8.0 Milestone

    • Breaking Change: Alter read_only plus default behaviour. #5886

      read_only fields will now always be excluded from writable fields.

      Previously read_only fields with a default value would use the default for create and update operations.

      In order to maintain the old behaviour you may need to pass the value of read_only fields when calling save() in the view:

        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
      

      Alternatively you may override save() or create() or update() on the serialiser as appropriate.

    • Correct allow_null behaviour when required=False #5888

      Without an explicit default, allow_null implies a default of null for outgoing serialisation. Previously such fields were being skipped when read-only or otherwise not required.

      Possible backwards compatibility break if you were relying on such fields being excluded from the outgoing representation. In order to restore the old behaviour you can override data to exclude the field when None.

      For example:

        @property
        def data(self):
            """
            Drop `maybe_none` field if None.
            """
            data = super().data()
            if 'maybe_none' in data and data['maybe_none'] is None:
                del data['maybe_none']
            return data
      
    • Refactor dynamic route generation and improve viewset action introspectibility. #5705

      ViewSets have been provided with new attributes and methods that allow it to introspect its set of actions and the details of the current action.

      • Merged list_route and detail_route into a single action decorator.
      • Get all extra actions on a ViewSet with .get_extra_actions().
      • Extra actions now set the url_name and url_path on the decorated method.
      • Enable action url reversing through .reverse_action() method (added in 3.7.4)
      • Example reverse call: self.reverse_action(self.custom_action.url_name)
      • Add detail initkwarg to indicate if the current action is operating on a collection or a single instance.

      Additional changes:

      • Deprecated list_route & detail_route in favor of action decorator with detail boolean.
      • Deprecated dynamic list/detail route variants in favor of DynamicRoute with detail boolean.
      • Refactored the router's dynamic route generation.
    • Fix formatting of the 3.7.4 release note #5704

    • Docs: Update DRF Writable Nested Serializers references #5711

    • Docs: Fixed typo in auth URLs example. #5713

    • Improve composite field child errors #5655

    • Disable HTML inputs for dict/list fields #5702

    • Fix typo in HostNameVersioning doc #5709

    • Use rsplit to get module and classname for imports #5712

    • Formalize URLPatternsTestCase #5703

    • Add exception translation test #5700

    • Test staticfiles #5701

    • Add drf-yasg to documentation and schema 3rd party packages #5720

    • Remove unused compat._resolve_model() #5733

    • Drop compat workaround for unsupported Python 3.2 #5734

    • Prefer iter(dict) over iter(dict.keys()) #5736

    • Pass python_requires argument to setuptools #5739

    • Remove unused links from docs #5735

    • Prefer https protocol for links in docs when available #5729

    • Add HStoreField, postgres fields tests #5654

    • Always fully qualify ValidationError in docs #5751

    • Remove unreachable code from ManualSchema #5766

    • Allowed customising API documentation code samples #5752

    • Updated docs to use pip show #5757

    • Load 'static' instead of 'staticfiles' in templates #5773

    • Fixed a typo in fields docs #5783

    • Refer to "NamespaceVersioning" instead of "NamespacedVersioning" in the documentation #5754

    • ErrorDetail: add __eq__/__ne__ and __repr__ #5787

    • Replace background-attachment: fixed in docs #5777

    • Make 404 & 403 responses consistent with exceptions.APIException output #5763

    • Small fix to API documentation: schemas #5796

    • Fix schema generation for PrimaryKeyRelatedField #5764

    • Represent serializer DictField as an Object in schema #5765

    • Added docs example reimplementing ObtainAuthToken #5802

    • Add schema to the ObtainAuthToken view #5676

    • Fix request formdata handling #5800

    • Fix authtoken views imports #5818

    • Update pytest, isort #5815 #5817 #5894

    • Fixed active timezone handling for non ISO8601 datetimes. #5833

    • Made TemplateHTMLRenderer render IntegerField inputs when value is 0. #5834

    • Corrected endpoint in tutorial instructions #5835

    • Add Django Rest Framework Role Filters to Third party packages #5809

    • Use single copy of static assets. Update jQuery #5823

    • Changes ternary conditionals to be PEP308 compliant #5827

    • Added links to 'A Todo List API with React' and 'Blog API' tutorials #5837

    • Fix comment typo in ModelSerializer #5844

    • Add admin to installed apps to avoid test failures. #5870

    • Fixed schema for UUIDField in SimpleMetadata. #5872

    • Corrected docs on router include with namespaces. #5843

    • Test using model objects for dotted source default #5880

    • Allow traversing nullable related fields #5849

    • Added: Tutorial: Django REST with React (Django 2.0) #5891

    • Add LimitOffsetPagination.get_count to allow method override #5846

    • Don't show hidden fields in metadata #5854

    • Enable OrderingFilter to handle an empty tuple (or list) for the 'ordering' field. #5899

    • Added generic 500 and 400 JSON error handlers. #5904

    Source code(tar.gz)
    Source code(zip)
  • 3.7.7(Jan 11, 2018)

  • 3.7.4(Dec 20, 2017)

    Point Release for 3.7.x series.

    • Schema: Extract method for manual_fields processing #5633

      Allows for easier customisation of manual_fields processing, for example to provide per-method manual fields. AutoSchema adds get_manual_fields, as the intended override point, and a utility method update_fields, to handle by-name field replacement from a list, which, in general, you are not expected to override.

      Note: AutoSchema.__init__ now ensures manual_fields is a list. Previously may have been stored internally as None.

    • Remove ulrparse compatability shim; use six instead #5579

    • Drop compat wrapper for TimeDelta.total_seconds() #5577

    • Clean up all whitespace throughout project #5578

    • Compat cleanup #5581

    • Add pygments CSS block in browsable API views #5584 #5587

    • Remove set_rollback() from compat #5591

    • Fix request body/POST access #5590

    • Rename test to reference correct issue #5610

    • Documentation Fixes #5611 #5612

    • Remove references to unsupported Django versions in docs and code #5602

    • Test Serializer exclude for declared fields #5599

    • Fixed schema generation for filter backends #5613

    • Minor cleanup for ModelSerializer tests #5598

    • Reimplement request attribute access w/ __getattr__ #5617

    • Fixed SchemaJSRenderer renders invalid Javascript #5607

    • Make Django 2.0 support official/explicit #5619

    • Perform type check on passed request argument #5618

    • Fix AttributeError hiding on request authenticators #5600

    • Update test requirements #5626

    • Docs: Serializer._declared_fields enable modifying fields on a serializer #5629

    • Fix packaging #5624

    • Fix readme rendering for PyPI, add readme build to CI #5625

    • Update tutorial #5622

    • Non-required fields with allow_null=True should not imply a default value #5639

    • Docs: Add allow_null serialization output note #5641

    • Update to use the Django 2.0 release in tox.ini #5645

    • Fix Serializer.data for Browsable API rendering when provided invalid data #5646

    • Docs: Note AutoSchema limitations on bare APIView #5649

    • Add .basename and .reverse_action() to ViewSet #5648

    • Docs: Fix typos in serializers documentation #5652

    • Fix override_settings compat #5668

    • Add DEFAULT_SCHEMA_CLASS setting #5658

    • Add docs note re generated BooleanField being required=False #5665

    • Add 'dist' build #5656

    • Fix typo in docstring #5678

    • Docs: Add UNAUTHENTICATED_USER = None note #5679

    • Update OPTIONS example from “Documenting Your API” #5680

    • Docs: Add note on object permissions for FBVs #5681

    • Docs: Add example to to_representation docs #5682

    • Add link to Classy DRF in docs #5683

    • Document ViewSet.action #5685

    • Fix schema docs typo #5687

    • Fix URL pattern parsing in schema generation #5689

    • Add example using source=‘*’ to custom field docs. #5688

    • Fix format_suffix_patterns behavior with Django 2 path() routes #5691

    See 3.7.4 Milestone

    Source code(tar.gz)
    Source code(zip)
  • 3.7.3(Nov 6, 2017)

  • 3.7.2(Nov 6, 2017)

    Point release for 3.7.x

    • Fixed Django 2.1 compatibility due to removal of django.contrib.auth.login()/logout() views. #5510
    • Add missing import for TextLexer. #5512
    • Adding examples and documentation for caching #5514
    • Include date and date-time format for schema generation #5511
    • Use triple backticks for markdown code blocks #5513
    • Interactive docs - make bottom sidebar items sticky #5516
    • Clarify pagination system check #5524
    • Stop JSONBoundField mangling invalid JSON #5527
    • Have JSONField render as textarea in Browsable API #5530
    • Schema: Exclude OPTIONS/HEAD for ViewSet actions #5532
    • Fix ordering for dotted sources #5533
    • Fix: Fields with allow_null=True should imply a default serialization value #5518
    • Ensure Location header is strictly a 'str', not subclass. #5544
    • Add import to example in api-guide/parsers #5547
    • Catch OverflowError for "out of range" datetimes #5546
    • Add djangorestframework-rapidjson to third party packages #5549
    • Increase test coverage for drf_create_token command #5550
    • Add trove classifier for Python 3.6 support. #5555
    • Add pip cache support to the Travis CI configuration #5556
    • Rename [wheel] section to [bdist_wheel] as the former is legacy #5557
    • Fix invalid escape sequence deprecation warnings #5560
    • Add interactive docs error template #5548
    • Add rounding parameter to DecimalField #5562
    • Fix all BytesWarning caught during tests #5561
    • Use dict and set literals instead of calls to dict() and set() #5559
    • Change ImageField validation pattern, use validators from DjangoImageField #5539
    • Fix processing unicode symbols in query_string by Python 2 #5552

    See 3.7.2 Milestone

    Source code(tar.gz)
    Source code(zip)
  • 3.7.1(Oct 16, 2017)

    • Fix Interactive documentation always uses false for boolean fields in requests #5492
    • Improve compatibility with Django 2.0 alpha. #5500 #5503
    • Improved handling of schema naming collisions #5486
    • Added additional docs and tests around providing a default value for dotted source fields #5489

    3.7.1 Milestone

    Source code(tar.gz)
    Source code(zip)
  • 3.7.0(Oct 6, 2017)

    Headline feature is the ability to add per-view customisation to schema generation.

    • Release Announcement: http://www.django-rest-framework.org/topics/3.7-announcement/
    • 3.7.0 Milestone: https://github.com/encode/django-rest-framework/milestone/49?closed=1
    Source code(tar.gz)
    Source code(zip)
Owner
Encode
Collaboratively funded software development.
Encode
Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints.

Flask Sugar is a web framework for building APIs with Flask, Pydantic and Python 3.6+ type hints. check parameters and generate API documents automatically. Flask Sugar是一个基于flask,pyddantic,类型注解的API框架, 可以检查参数并自动生成API文档

null 60 Nov 29, 2021
Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs

chisel Chisel is a light-weight Python WSGI application framework built for creating well-documented, schema-validated JSON web APIs. Here are its fea

Craig Hobbs 2 Oct 1, 2021
NO LONGER MAINTAINED - A Flask extension for creating simple ReSTful JSON APIs from SQLAlchemy models.

NO LONGER MAINTAINED This repository is no longer maintained due to lack of time. You might check out the fork https://github.com/mrevutskyi/flask-res

null 1k Oct 20, 2021
NO LONGER MAINTAINED - A Flask extension for creating simple ReSTful JSON APIs from SQLAlchemy models.

NO LONGER MAINTAINED This repository is no longer maintained due to lack of time. You might check out the fork https://github.com/mrevutskyi/flask-res

null 1k Jan 15, 2021
Web3.py plugin for using Flashbots' bundle APIs

This library works by injecting a new module in the Web3.py instance, which allows submitting "bundles" of transactions directly to miners. This is done by also creating a middleware which captures calls to eth_sendBundle and eth_callBundle, and sends them to an RPC endpoint which you have specified, which corresponds to mev-geth.

Georgios Konstantopoulos 118 Nov 21, 2021
Web3.py plugin for using Flashbots' bundle APIs

This library works by injecting a new module in the Web3.py instance, which allows submitting "bundles" of transactions directly to miners. This is do

Flashbots 118 Nov 21, 2021
A Python package to easily create APIs in Python.

API_Easy An Python Package for easily create APIs in Python pip install easy-api-builder Requiremnets: <= python 3.6 Required modules --> Flask Docume

Envyre-Coding 2 Nov 9, 2021
Goblet is an easy-to-use framework that enables developers to quickly spin up fully featured REST APIs with python on GCP

GOBLET Goblet is a framework for writing serverless rest apis in python in google cloud. It allows you to quickly create and deploy python apis backed

Austen 31 Nov 23, 2021
Containers And REST APIs Workshop

Containers & REST APIs Workshop Containers vs Virtual Machines Ferramentas Podman: https://podman.io/ Docker: https://www.docker.com/ IBM CLI: https:/

Vanderlei Munhoz 7 Nov 4, 2021
web.py is a web framework for python that is as simple as it is powerful.

web.py is a web framework for Python that is as simple as it is powerful. Visit http://webpy.org/ for more information. The latest stable release 0.62

null 5.6k Nov 24, 2021
Django Ninja - Fast Django REST Framework

Django Ninja is a web framework for building APIs with Django and Python 3.6+ type hints.

Vitaliy Kucheryaviy 1.7k Dec 2, 2021
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 15.6k Dec 1, 2021
Fast, asynchronous and elegant Python web framework.

Warning: This project is being completely re-written. If you're curious about the progress, reach me on Slack. Vibora is a fast, asynchronous and eleg

vibora.io 5.7k Nov 26, 2021
cirrina is an opinionated asynchronous web framework based on aiohttp

cirrina cirrina is an opinionated asynchronous web framework based on aiohttp. Features: HTTP Server Websocket Server JSON RPC Server Shared sessions

André Roth 33 Nov 24, 2021
The Web framework for perfectionists with deadlines.

Django Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Thanks for checking it out. All docu

Django 60.9k Nov 26, 2021
The Python micro framework for building web applications.

Flask Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to co

The Pallets Projects 57.2k Nov 27, 2021
Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.

Tornado Web Server Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking ne

null 20.3k Dec 2, 2021
The comprehensive WSGI web application library.

Werkzeug werkzeug German noun: "tool". Etymology: werk ("work"), zeug ("stuff") Werkzeug is a comprehensive WSGI web application library. It began as

The Pallets Projects 5.9k Nov 24, 2021
Async Python 3.6+ web server/framework | Build fast. Run fast.

Sanic | Build fast. Run fast. Build Docs Package Support Stats Sanic is a Python 3.6+ web server and web framework that's written to go fast. It allow

Sanic Community Organization 15.6k Nov 22, 2021