So this is the first time I use djangorestframework-bulk for implementing batch requests. If I understand correctly, you should be able get this functionality out-of-the-box by just having your *ViewSet classes inherit also from the app's mixins like BulkUpdateModelMixin or viewsets like BulkUpdateAPIView.
As stated on the notes in the repo:
Most API urls have two URL levels for each resource:
url(r'foo/', ...)
url(r'foo/(?P<pk>\d+)/', ...)
The second url however is not applicable for bulk operations because
the url directly maps to a single resource. Therefore all bulk generic
views only apply to the first url.
However, when I try to perform PUT or PATCH bulk requests (haven't tried with DELETE) to an endpoint in my app, like:
http://localhost:8000/api/users/
I get the following error:
PUT http://localhost:8080/api/users/ 405 (METHOD NOT ALLOWED)
Is there any additional configuration I need to do in order for this url to allow PUT and PATCH requests and have my viewset's update() and partial_update() process such requests?
Thanks!!
Your problem is that you've implemented the bulk methods through the BulkUpdateModelMixin, but you don't have a proper router for your ViewSet. You now need, for example, put to go to bulk_update rather than just update.
Check out here for an example of how to set up your own router to allow for bulk update functionality with DRF ViewSets. Basically, map out the verbs to call the proper method.
Related
Can I nest the viewsets and create routes that takes pk as parameters of the url?
basically:
class TaskView(viewsets.ModelViewSet):
model = Task
This works fine and it's mapped to the task/ url, so task/1/ gives the data of the task with id 1. now, i want to create an instance of the task, having CRUD operations as for the task, so i would like to have
class InstanceView(viewsets.ModelViewSet):
model = Instance
mapped to task/{pk}/instance, where pk is the id of the task.
how can i do that? is it possible?
PS: i saw that there are #action and #link but using them i loose the power of having everything made by the framework.
There are two plugins out there for making this happen: drf-nested-viewsets and drf-nested-routers.
DRF Nested Routers works on a router level and makes it easy to do nested viewsets, as the nested parameters are passed into every method for easy reference. The README in the repository gives an overview of what can be done. This does not appear to allow for nested DefaultRouters (which include the API root page).
DRF Nested Viewsets (full disclosure: created by me) is primarily meant for hyperlinked scenarios (where everything uses a HyperlinkedModelSerializer) and isn't as easy to use. It handles hyperlinked relations by mapping the current URL arguments to generate nested urls on linked models. A bit of documentation is available at the original gist.
Both plugins require overriding get_queryset for filtering nested querysets. For DRF Nested Viewsets this requires pulling url arguments from self.kwargs within the viewset and using those to filter, I am not sure how it is done using DRF Nested Routers, but it mostly likely isn't much different.
Note: If you do not need hyperlinked relations, this can be done without third-party plugins by just overriding get_queryset and filtering off of url arguments.
DRF extensions also provides a way to create nested routes.
I'm working with DRF and I'm struggling to create a URL like this:
/myApp/languages/<language_id>/countries/<country_id>/
Thanks to a previous question, I know that I can easily use the #action method decorator within DRF router's extra actions, to handle URLs with this format:
/myApp/languages/<language_id>/countries/
However, I haven't found a way to register the new URL that I need, where I include an ID for the second resource:
/myApp/languages/<language_id>/countries/<country_id>/
How can I do it with DRF?
Instead of
/myApp/languages/<language_id>/countries/<country_id>/
Please try below:
/myApp/languages/countries/<language_id>/<country_id>/
Python Eve: Is there a way to avoid resource lookup passed through url in eve framework?
e.g. /people/(string:user_id)/hobbies
I want to avoid user_id lookup in the endpoint request where I will handle user_id field in a custom way.
You can select which methods are allowed for each resource, or globally.
In this case you could limit the GET for people by setting the item item_methods property. For example, if you want to allow only DELETE for the item, you need to add the following in the endpoint definition:
'item_methods': ['DELETE']
The documentation says:
item_methods:
A list of HTTP methods supported at item endpoint. Allowed values: GET, PATCH, PUT and DELETE. PATCH or, for clients not supporting PATCH, POST with the X-HTTP-Method-Override header tag. Locally overrides ITEM_METHODS.
I have created a number of Django-tastypie resource definitions in resources.py. Most of them will be created by posting from javascript side (backbone-tastypie), but some of them I would like to be able to create right from python code/django views.
The reason for this is that object creation logic should be kept in one place, as well as authorization params.
Is there some neat way to create TastyPie ModelResource inside Python code? (may be making a "post" with "Requests" module?).
If i understand you right, your usecase is described in tastypie cookbook: http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-your-resource-in-regular-views
I am adding MetaWeblog API support to a Django CMS, and am not quite sure how to layer the application.
I am using django_xmlrpc, which allows me to map to parameterised functions for each request. It is just a case of what level do I hook in calls to the django application from the service functions (AddPage, EditPage etc)
For django-page-cms, and I suppose many django apps, the business logic and validation is contained within the forms. In this case there is PageForm(forms.ModelForm) and PageAdmin(ModelAdmin), which both contain a lot of logic and validation.
If I am to build an API to allow maintenance of pages and content, does this mean I should be programmatically creating and filling a PageAdmin instance? Then catching any exceptions, and converting to their api equivalent? Or would this be a bad idea - misusing what forms are intended for?
The other option is refactoring the code so that business and logic is kept outside of the form classes. Then I would have the form and api, both go through the separate business logic.
Any other alternatives?
What would be the best solution?
Web services API's are just more URL's.
These WS API URL's map to view functions.
The WS view functions handle GET and POST (and possibly PUT and DELETE).
The WS view functions use Forms as well as the Models to make things happen.
It is, in a way, like an admin interface. Except, there's no HTML.
The WS view functions respond with JSON messages or XML messages.
It seems python does not provide this out of the box. But there is something called abc module:
I quote from http://www.doughellmann.com/PyMOTW/abc/ "By defining an abstract base class, you can define a common API for a set of subclasses. This capability is especially useful in situations where a third-party is going to provide implementations..." => the goal of an API, defining a contract.