README.rst 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. Django REST Framework Bulk
  2. ==========================
  3. .. image:: https://badge.fury.io/py/djangorestframework-bulk.png
  4. :target: http://badge.fury.io/py/djangorestframework-bulk
  5. Django REST Framework bulk CRUD view mixins.
  6. Overview
  7. --------
  8. Django REST Framework comes with many generic views however none
  9. of them allow to do bulk operations such as create, update and delete.
  10. To keep the core of Django REST Framework simple, its maintainer
  11. suggested to create a separate project to allow for bulk operations
  12. within the framework. That is the purpose of this project.
  13. Requirements
  14. ------------
  15. * Python (2.6, 2.7 and 3.3)
  16. * Django 1.3+
  17. * Django REST Framework >= 2.2.5 (when bulk features were added to serializers), < 3.0
  18. Installing
  19. ----------
  20. Using pip::
  21. $ pip install djangorestframework-bulk
  22. or from source code::
  23. $ pip install -e git+http://github.com/miki725/django-rest-framework-bulk#egg=djangorestframework-bulk
  24. Example
  25. -------
  26. The bulk views (and mixins) are very similar to Django REST Framework's own
  27. generic views (and mixins)::
  28. from rest_framework_bulk import ListBulkCreateUpdateDestroyAPIView
  29. class FooView(ListBulkCreateUpdateDestroyAPIView):
  30. model = FooModel
  31. The above will allow to create the following queries
  32. ::
  33. # list queryset
  34. GET
  35. ::
  36. # create single resource
  37. POST
  38. {"field":"value","field2":"value2"} <- json object in request data
  39. ::
  40. # create multiple resources
  41. POST
  42. [{"field":"value","field2":"value2"}]
  43. ::
  44. # update multiple resources (requires all fields)
  45. PUT
  46. [{"field":"value","field2":"value2"}] <- json list of objects in data
  47. ::
  48. # partial update multiple resources
  49. PATCH
  50. [{"field":"value"}] <- json list of objects in data
  51. ::
  52. # delete queryset (see notes)
  53. DELETE
  54. Router
  55. ------
  56. The bulk router can map automatically the bulk actions::
  57. from rest_framework_bulk.routes import BulkRouter
  58. class UserViewSet(BulkModelViewSet):
  59. model = User
  60. def allow_bulk_destroy(self, qs, filtered):
  61. """Don't forget to fine-grain this method"""
  62. router = BulkRouter()
  63. router.register(r'users', UserViewSet)
  64. Notes
  65. -----
  66. Most API urls have two URL levels for each resource:
  67. 1. ``url(r'foo/', ...)``
  68. 2. ``url(r'foo/(?P<pk>\d+)/', ...)``
  69. The second url however is not applicable for bulk operations because
  70. the url directly maps to a single resource. Therefore all bulk
  71. generic views only apply to the first url.
  72. There are multiple generic view classes in case only a certail
  73. bulk functionality is required. For example ``ListBulkCreateAPIView``
  74. will only do bulk operations for creating resources.
  75. For a complete list of available generic view classes, please
  76. take a look at the source code at ``generics.py`` as it is mostly
  77. self-explanatory.
  78. Most bulk operations are pretty safe in terms of how they operate,
  79. that is you explicitly describe all requests. For example, if you
  80. need to update 3 specific resources, you have to explicitly identify
  81. those resources in the request's ``PUT`` or ``PATCH`` data.
  82. The only exception to this is bulk delete. Consider a ``DELETE``
  83. request to the first url. That can potentially delete all resources
  84. without any special confirmation. To try to account for this, bulk delete
  85. mixin allows to implement a hook to determine if the bulk delete
  86. request should be allowed::
  87. class FooView(BulkDestroyAPIView):
  88. def allow_bulk_destroy(self, qs, filtered):
  89. # custom logic here
  90. # default checks if the qs was filtered
  91. # qs comes from self.get_queryset()
  92. # filtered comes from self.filter_queryset(qs)
  93. return qs is not filtered
  94. By default it checks if the queryset was filtered and if not will not
  95. allow the bulk delete to complete. The logic here is that if the request
  96. is filtered to only get certain resources, more attention was payed hence
  97. the action is less likely to be accidental. On how to filter requests,
  98. please refer to Django REST
  99. `docs <http://www.django-rest-framework.org/api-guide/filtering>`_.
  100. Either way, please use bulk deletes with extreme caution since they
  101. can be dangerous.