miki725 / django-rest-framework-bulk Goto Github PK
View Code? Open in Web Editor NEWDjango REST Framework bulk CRUD view mixins
License: Other
Django REST Framework bulk CRUD view mixins
License: Other
def login_view(request):
next = request.GET.get('next')
title = 'Вхід'
form = UserLoginForms(request.POST or None)
if form.is_valid():
username = form.changed_data.get('username')
password = form.changed_data.get('password')
user = authenticate(username=username, password=password)
login(request, user)
if next:
return redirect(next)
return redirect('/')
return render(request, "form.html", {"form": form, "title": title})
def register_view(request):
next = request.GET.get('next')
title = 'Регістрація'
form = UserRegisterForm(request.POST or None)
if form.is_valid():
user = form.save(commit=False)
password = form.cleaned_data.get('password')
user.set_password()
user.save()
new_user = authenticate(username=user.username, password=password)
login(request, new_user)
if next:
return redirect(next)
return redirect('/')
context = {
'form': form,
'title': title,
}
return render(request, "form.html", context)
'list' object has no attribute 'get'
'list' object has no attribute 'get'
I get this error:
AttributeError at /api/activities/
'RelationsList' object has no attribute 'id'
When doing a bulk create:
[{"activity_type":"text","datetime":"2014-02-26T18:06:00","device_id":10950},{"activity_type":"text","datetime":"2014-02-26T18:05:13","device_id":10948}]
Using this setup:
class ActivitySerializer(serializers.ModelSerializer):
class Meta:
exclude = ('user', )
model = Activity
class UserViewSetMixin(object):
def get_queryset(self):
user = self.request.user
qs = super(UserViewSetMixin, self).get_queryset()
return qs.filter(user=user)
def pre_save(self, obj):
obj.user = self.request.user
class ActivityViewSet(UserViewSetMixin, ListBulkCreateUpdateDestroyAPIView):
model = Activity
permission_classes = (permissions.IsAuthenticated, IsUser, )
serializer_class = ActivitySerializer
To install it from git, you set the command line to
$ pip install -r git+http://github.com/miki725/django-rest-framework-bulk#egg=djangorestframework-bulk
Shouldn't it be
$ pip install [-e] git+http://github.com/miki725/django-rest-framework-bulk#egg=djangorestframework-bulk>
I think -r stands for a requirements.txt file, am I right ?
I've tried creating a very simple API endpoint following the README:
from django.db import models
from rest_framework import serializers
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateAPIView
class Foo(models.Model):
name = models.CharField(max_length=20)
class Meta:
app_label = "foobar"
class FooSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class Meta(object):
model = Foo
list_serializer_class = BulkListSerializer
class FooView(ListBulkCreateUpdateAPIView):
queryset = Foo.objects.all()
serializer_class = FooSerializer
I've configured a URL for FooView
and am able to load the built in rest_framework
html page for this API endpoint. I've also created a few instances of the Foo
model for testing.
However, when I attempt to make an HTTP PUT/PATCH request to this endpoint to update one of the existing instances, I get a successful return code but no update actually occurs.
curl 'http://127.0.0.1:8000/foo/' -X PUT -H 'Cookie: csrftoken=M8jkbJtUKwjKB7zya8JYvxqJVxkRaPgG' -H 'X-CSRFToken: M8jkbJtUKwjKB7zya8JYvxqJVxkRaPgG' --data 'id=1&name=D' --compressed
The response is simply an empty list []
and the instance with id=1 retains its old name.
I've created a sample project to reproduce this, and would really appreciate any help. I am unable to determine if this is a bug in DRF, DRF-bulk, or a misunderstanding on my part.
[Update]
I tried testing a POST request, like so, and it did create a new object:
curl 'http://127.0.0.1:8000/foo/' -X POST -H 'Cookie: csrftoken=M8jkbJtUKwjKB7zya8JYvxqJVxkRaPgG' -H 'X-CSRFToken: M8jkbJtUKwjKB7zya8JYvxqJVxkRaPgG' --data 'name=D' --compressed
The response for this request is: {"id":4,"name":"D"}
However, trying to create a new object with PUT does not work:
curl 'http://127.0.0.1:8000/foo/' -X PUT -H 'Cookie: csrftoken=M8jkbJtUKwjKB7zya8JYvxqJVxkRaPgG' -H 'X-CSRFToken: M8jkbJtUKwjKB7zya8JYvxqJVxkRaPgG' --data 'name=E'
The response for this is: []
I believe that PUT/PATCH support for django_rest_framework-bulk is broken at this point. Python package info is:
Django==1.8
djangorestframework==3.4.4
djangorestframework-bulk==0.2.1
DRF creates objects individually - which ends up being pretty slow if you post, say, 200 items to a "bulk" endpoint. Still better than the alternative, but still not great. It would be nice to use bulk_create instead.
I'm trying to wrote test for my application ( I have bulk creation on one api ) but iI'm blocked because the rest_framework api client does not allow me to execute post with a list as data
error:
Traceback (most recent call last):
File "/Users/andrea/Documents/workspace/MakrShakrPortbl/ingredient/tests.py", line 79, in test_buld_ingridient_operation
creation_response = self.client.post(reverse(self.ingredienttListViewName),self.ingredient_data_list)
File "/Users/andrea/Documents/workspace/MakrShakrPortbl/venv/lib/python2.7/site-packages/rest_framework/test.py", line 168, in post
path, data=data, format=format, content_type=content_type, **extra)
File "/Users/andrea/Documents/workspace/MakrShakrPortbl/venv/lib/python2.7/site-packages/rest_framework/test.py", line 89, in post
data, content_type = self._encode_data(data, format, content_type)
File "/Users/andrea/Documents/workspace/MakrShakrPortbl/venv/lib/python2.7/site-packages/rest_framework/test.py", line 64, in _encode_data
ret = renderer.render(data)
File "/Users/andrea/Documents/workspace/MakrShakrPortbl/venv/lib/python2.7/site-packages/rest_framework/renderers.py", line 678, in render
return encode_multipart(self.BOUNDARY, data)
File "/Users/andrea/Documents/workspace/MakrShakrPortbl/venv/lib/python2.7/site-packages/django/test/client.py", line 168, in encode_multipart
for (key, value) in data.items():
AttributeError: 'list' object has no attribute 'items'
I'm working on osx yosemite 10.10.3
pip freeze with virtualenv actived:
Django==1.8.2
-e https://github.com/umutbozkurt/django-rest-framework-mongoengine#egg=django_rest_framework_mongoengine-master
djangorestframework==3.1.3
djangorestframework-bulk==0.2.1
mongoengine==0.9.0
pymongo==2.8.1
wsgiref==0.1.2
no problem on creation,update reported
Im trying to bulk upload data using PUT, but am getting keyError ID, this is expected as I do not have the ID in the JSON data.
however there is another unique field in the JSON Data and I could use that to upload, is it possible to do this?
Model:
ID - unique auto increment
PDID - another unique value
NAME
Mobile
JSON
[{"Name": "Billy Bob", "Mobile": "015525 58165", "PDID": "PA8AMY1"}, {"Name": "John Smith", "Mobile": "159815588, "PDID": "PQ0FT0P"}]
Thanks
I ran into an issue with a model I was trying to bulk patch that also has a unique_together constraint. Traceback is below. The issue here is that the UniqueTogetherValidator expects to be called from a serializer with a single related instance (i.e. a normal update serializer). But the serializer is in fact instantiated with a queryset.
TBH I don't entirely understand why serializer.instance
is being set to a queryset. But anyway.
Traceback (most recent call last):
File ".../django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File ".../django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File ".../django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File ".../rest_framework/viewsets.py", line 87, in view
return self.dispatch(request, *args, **kwargs)
File ".../rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File ".../rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File ".../rest_framework_bulk/drf3/mixins.py", line 79, in partial_bulk_update
return self.bulk_update(request, *args, **kwargs)
File ".../rest_framework_bulk/drf3/mixins.py", line 73, in bulk_update
serializer.is_valid(raise_exception=True)
File ".../rest_framework/serializers.py", line 213, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File ".../rest_framework/serializers.py", line 557, in run_validation
value = self.to_internal_value(data)
File ".../rest_framework/serializers.py", line 593, in to_internal_value
validated = self.child.run_validation(item)
File ".../rest_framework/serializers.py", line 409, in run_validation
self.run_validators(value)
File ".../rest_framework/fields.py", line 498, in run_validators
validator(value)
File ".../rest_framework/validators.py", line 142, in __call__
queryset = self.exclude_current_instance(attrs, queryset)
File ".../rest_framework/validators.py", line 135, in exclude_current_instance
return queryset.exclude(pk=self.instance.pk)
AttributeError: 'QuerySet' object has no attribute 'pk'
My workaround was to take advantage of the 'id' attribute that the bulk serializer keeps track of and write a custom unique_together validator.
# validators.py
from rest_framework.validators import UniqueTogetherValidator
class BulkUniqueTogetherValidator(UniqueTogetherValidator):
def exclude_current_instance(self, attrs, queryset):
if attrs.get('id'):
return queryset.exclude(pk=attrs['id'])
return queryset
# serializers.py
from .validators import BulkUniqueTogetherValidator
class ThingSerializer(serializers.HyperlinkedModelSerializer):
<...properties>
def get_unique_together_validators(self):
return [BulkUniqueTogetherValidator(
queryset=Thing.objects.all(),
fields=('field1', 'field2'),
)]
Right now, only the tar.gz
file is being distributed on PyPI for djangorestframework-bulk, which isn't that much of an issue, but it does add some time to installing the package.
This package should be compatible with the Wheel format, considering it doesn't appear to have any C dependencies and it is compatible with both Python 2 and 3. As a result, you should only need to generate a universal wheel and then everyone (on all systems) will get the ability to install djangorestframework-bulk with just the wheel, without having to do any extra work.
Hello,
When installing by pip with the command "pip install djangorestframework-bulk" the file routes.py is not present in the sources.
By adding it manually from the sources to the installed folder, it does work!
I guess I should add it in the project itself and not in the sources till this is fixed.
Regards,
Alex
For those of us still on Ubuntu 12.04 LTS, we've only got access to Python 2.7 and 3.2.
Here's the error I get when trying to pip install djangorestframework-bulk
:
Downloading/unpacking djangorestframework-bulk
Running setup.py egg_info for package djangorestframework-bulk
Requirement already satisfied (use --upgrade to upgrade): django in /home/paul/.virtualenvs/api/lib/python3.2/site-packages (from djangorestframework-bulk)
Requirement already satisfied (use --upgrade to upgrade): djangorestframework in /home/paul/.virtualenvs/api/lib/python3.2/site-packages (from djangorestframework-bulk)
Installing collected packages: djangorestframework-bulk
Running setup.py install for djangorestframework-bulk
warning: install_data: setup script did not provide a directory for 'rest_framework_bulk' -- installing right in '/home/paul/.virtualenvs/api'
error: can't copy 'rest_framework_bulk': doesn't exist or not a regular file
Complete output from command /home/paul/.virtualenvs/api/bin/python3 -c "import setuptools;__file__='/home/paul/.virtualenvs/api/build/djangorestframework-bulk/setup.py';exec(compile(open(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --single-version-externally-managed --record /tmp/pip-4qgzps-record/install-record.txt --install-headers /home/paul/.virtualenvs/api/include/site/python3.2:
running install
running build
running build_py
running install_lib
running install_data
warning: install_data: setup script did not provide a directory for 'rest_framework_bulk' -- installing right in '/home/paul/.virtualenvs/api'
error: can't copy 'rest_framework_bulk': doesn't exist or not a regular file
----------------------------------------
Command /home/paul/.virtualenvs/api/bin/python3 -c "import setuptools;__file__='/home/paul/.virtualenvs/api/build/djangorestframework-bulk/setup.py';exec(compile(open(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --single-version-externally-managed --record /tmp/pip-4qgzps-record/install-record.txt --install-headers /home/paul/.virtualenvs/api/include/site/python3.2 failed with error code 1 in /home/paul/.virtualenvs/api/build/djangorestframework-bulk
Storing complete log in /home/paul/.pip/pip.log
Are viewsets supported? Maybe with some mixin magic?
If not maybe I can help implement them.
This project seems to be quite heavily used, but has not received any updates since 2015. @miki725 is it dead?
Background
I needed to write my own view, using the provided bulk mixins.
Problem
I first tried importing using from rest_framework_bulk import mixins as bulk_mixins
. Then, got the following error AttributeError: 'module' object has no attribute 'BulkCreateModelMixin'
when trying to use bulk_mixins.BulkCreateModelMixin
.
In the Django shell:
>>> from rest_framework_bulk import mixins as bulk_mixins
>>> dir(bulk_mixins)
['CreateModelMixin', 'DestroyModelMixin', 'Http404', 'ListModelMixin', 'Response', 'RetrieveModelMixin', 'UpdateModelMixin', 'ValidationError', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_get_validation_exclusions', 'api_settings', 'clone_request', 'status', 'unicode_literals', 'warnings']
Whereas:
>>> from rest_framework_bulk.generics import bulk_mixins
>>> dir(bulk_mixins)
['BulkCreateModelMixin', 'BulkDestroyModelMixin', 'BulkUpdateModelMixin', 'CreateModelMixin', 'Response', 'ValidationError', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'print_function', 'status', 'unicode_literals']
Solution
from rest_framework_bulk.generics import bulk_mixins
Having fixed the above problem, I stumped with the following:
'RelationsList' object has no attribute 'priority'
.When a non-bulk POST request (with just one object, not a list of objects) is made, it saves successfully and the response throws no error.
In my view I have:
def get_serializer_class(self):
if self.request.method == 'GET':
return NestedSelectedPlaceSerializer
return SelectedPlaceSerializer
My serializer classes are:
class SelectedPlaceSerializer(serializers.ModelSerializer):
class Meta:
model = SelectedPlace
fields = ('user', 'place', 'priority')
class NestedSelectedPlaceSerializer(serializers.ModelSerializer):
place = PlaceSerializer()
class Meta:
model = SelectedPlace
fields = ('place', 'priority')
Traceback
Environment:
Request Method: POST
Request URL: https://127.0.0.1:8443/api/places/selected
Traceback:
File "/home/user/venv/project1/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
139. response = response.render()
File "/home/user/venv/project1/local/lib/python2.7/site-packages/django/template/response.py" in render
105. self.content = self.rendered_content
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/response.py" in rendered_content
59. ret = renderer.render(self.data, media_type, context)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/renderers.py" in render
592. context = self.get_context(data, accepted_media_type, renderer_context)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/renderers.py" in get_context
542. raw_data_post_form = self.get_raw_data_form(view, 'POST', request)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/renderers.py" in get_raw_data_form
492. content = renderer.render(serializer.data, accepted, context)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/serializers.py" in data
573. self._data = self.to_native(obj)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/serializers.py" in to_native
349. value = field.field_to_native(obj, field_name)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/fields.py" in field_to_native
334. return super(WritableField, self).field_to_native(obj, field_name)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/fields.py" in field_to_native
198. value = get_component(value, component)
File "/home/user/venv/project1/local/lib/python2.7/site-packages/rest_framework/fields.py" in get_component
56. val = getattr(obj, attr_name)
Exception Type: AttributeError at /api/places/selected/
Exception Value: 'RelationsList' object has no attribute 'priority'
[DESCRIPTION]
When making a PUT request to a BulkModelViewSet
, using a simple DRF ModelSerializer
with all fields automatically generated - no field specified by hand -and with list_serializer_class
attribute being BulkListSerializer
the application crashes at this line and raises a KeyError
for 'id'
key.
[REASON]
When DRF ListSerializer
passes validated_data
to the update()
method the given validated_data
don't contain the id of the object.
[FIX]
DRF don't return id
in validated_data
anymore unless the field is explicitly declared in the serializer (id = serializers.IntegerField()
) so you have to do that in order for it to work. I don't believe we should add it to DRF-bulk BulkListSerializer
though, since pk
might not be the id
field, what do you think? Raising an exception if the 'id'
key is not in validated_data
might be a better solution.
[ENVIRONMENT]
- Debian GNU/Linux 8 (8.2)
- Django Version: 1.5.6
- Django-rest-framework Version: 3.2.4
- Python Version: 2.7.8
[TRACEBACK]
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
77. return view_func(*args, **kwargs)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
87. return self.dispatch(request, *args, **kwargs)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
466. response = self.handle_exception(exc)
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
463. response = handler(request, *args, **kwargs)
File "/home/adelaby/Development/contexte-site/contexte/libs/utils/views/mixins.py" in bulk_update
42. self.perform_bulk_update(serializer)
File "/home/adelaby/Development/contexte-site/contexte/apps/users/views/rest.py" in perform_bulk_update
131. super(UsersViewSet, self).perform_bulk_update(serializer)
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/mixins.py" in perform_bulk_update
85. return self.perform_update(serializer)
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/mixins.py" in perform_update
82. serializer.save()
File "/home/adelaby/.virtualenvs/contexte/local/lib/python2.7/site-packages/rest_framework/serializers.py" in save
643. self.instance = self.update(self.instance, validated_data)
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/serializers.py" in update
43. for i in all_validated_data
File "/home/adelaby/.virtualenvs/contexte/src/djangorestframework-bulk/rest_framework_bulk/drf3/serializers.py" in <dictcomp>
43. for i in all_validated_data
class FooView(BulkDestroyAPIView):
def allow_bulk_destroy(self, qs, filtered):
# custom logic here
# default checks if the qs was filtered
# qs comes from self.get_queryset()
# filtered comes from self.filter_queryset(qs)
return qs is not filtered
By default it checks if the queryset was filtered and if not will not allow the bulk delete to complete.
I understood this to mean bulk_destroy will only apply to filtered querysets. However, the default implementation returns true when the queryset is not filtered and false when it is.
Then BulkDestroyModelMixin logic only allows unfiltered querysets to be destroyed.
Is this correct and intentional?
Greetings,
I liked the framework and have been using it, but wondering if the framework supports HyperLinkedModelSerializer fields when doing an update.
I went ahead and made some changes to get this to work, but wondering if it is already supported.
thanks
vjnt
a 400 bad request would be much better.
I think it's because id_field.get_value(data)
here https://github.com/miki725/django-rest-framework-bulk/blob/master/rest_framework_bulk/drf3/serializers.py#L26 returns an rest_framework.fields.empty
object.
versions:
djangorestframework==3.1.1
djangorestframework-bulk==0.2
Traceback (most recent call last):
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework/viewsets.py", line 85, in view
return self.dispatch(request, *args, **kwargs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework/views.py", line 452, in dispatch
response = self.handle_exception(exc)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework/views.py", line 449, in dispatch
response = handler(request, *args, **kwargs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework_bulk/drf3/mixins.py", line 79, in partial_bulk_update
return self.bulk_update(request, *args, **kwargs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework_bulk/drf3/mixins.py", line 74, in bulk_update
self.perform_bulk_update(serializer)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework_bulk/drf3/mixins.py", line 85, in perform_bulk_update
return self.perform_update(serializer)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework/mixins.py", line 73, in perform_update
serializer.save()
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 598, in save
self.instance = self.update(self.instance, validated_data)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/rest_framework_bulk/drf3/serializers.py", line 51, in update
'{}__in'.format(id_attr): all_validated_data_by_id.keys(),
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/query.py", line 679, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/query.py", line 697, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1301, in add_q
clause, require_inner = self._add_q(where_part, self.used_aliases)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1328, in _add_q
current_negated=current_negated, connector=connector, allow_joins=allow_joins)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1200, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1096, in build_lookup
return final_lookup(lhs, rhs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/lookups.py", line 96, in __init__
self.rhs = self.get_prep_lookup()
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/lookups.py", line 134, in get_prep_lookup
return self.lhs.output_field.get_prep_lookup(self.lookup_name, self.rhs)
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 729, in get_prep_lookup
return [self.get_prep_value(v) for v in value]
File "/home/flc/.virtualenvs/drfbulktest/local/lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 985, in get_prep_value
return int(value)
TypeError: int() argument must be a string or a number, not 'classobj'```
BulkSerializerMixin.to_internal_values(...) does this:
request_method = getattr(getattr(self.context.get('view'), 'request'), 'method', '')
So, given the serializer code:
from rest_framework import serializers
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
class SimpleSerializer(BulkSerializerMixin, serializers.Serializer):
simple_field = serializers.CharField()
class Meta:
list_serializer_class = BulkListSerializer
And a test case:
from django.test import TestCase
from myproject.serializers import SimpleSerializer
class SimpleSerializerTestCase(TestCase):
def test_single(self):
data = {
"simple_field": "foo",
}
serializer = SimpleSerializer(data=data)
self.assertTrue(serializer.is_valid())
def test_multiple(self):
data = [
{"simple_field": "foo"},
{"simple_field": "bar"},
]
serializer = SimpleSerializer(data=data, many=True)
self.assertTrue(serializer.is_valid())
both of these tests will fail with
Traceback (most recent call last):
...
File ".../local/lib/python2.7/site-packages/rest_framework_bulk/drf3/serializers.py", line 19, in to_internal_value
request_method = getattr(getattr(self.context.get('view'), 'request'), 'method', '')
AttributeError: 'NoneType' object has no attribute 'request'
One can initialize the Serializer with a mock, to get rid of the problem:
import mock
view = mock.Mock()
view.request.method = "POST"
serializer = SimpleSerializer(data=data, context={"view": view})
self.assertTrue(serializer.is_valid())
but ideally, a Serializer should be testable in isolation, with no notion of a view involved.
I suggest one or more of:
My apologies if I missed something obvious.
BulkSerializerMixin uses get_value()
to get the id of an object, but doesn't use to_internal_value()
to convert the id to the proper internal value. This works fine for integer ids, but it breaks for UUIDs because the all_validated_data_by_id
in BulkListSerializer.update
constructs a dict by string id and then tries to get values for instance ids (which are UUIDs and thus not in the dictionary.)
The get_initial
of a serializer normally looks like this:
def get_initial(self):
if hasattr(self, 'initial_data'):
return OrderedDict([
(field_name, field.get_value(self.initial_data))
for field_name, field in self.fields.items()
if (field.get_value(self.initial_data) is not empty) and
not field.read_only
])
return OrderedDict([
(field.field_name, field.get_initial())
for field in self.fields.values()
if not field.read_only
])
This breaks with AttributeError: 'list' object has no attribute 'get'
if initial data is a list, such as after a POST on the browsable api (using the raw data tab to submit multiple objects).
I've fixed this in my code by switching get_initial
on BulkSerializerMixin
to:
def get_initial(self):
return OrderedDict([
(field.field_name, field.get_initial())
for field in self.fields.values()
if not field.read_only
])
A better solution might be to not set initial_data
during a POST, but this was easier for me to find.
Subj. They are exist in DRF.
a maintainer of the drf-extensions here
Posting to a BulkModelViewSet using the DRF api browser causes the following exception to be thrown. NB: the data has already been written to the db successfully before the exception happens:
TypeError at /usage_records/
'BulkListSerializer' object is not iterable
Request Method: POST
Request URL: http://127.0.0.1:8000/usage_records/
Django Version: 1.7.4
Exception Type: TypeError
Exception Value:
'BulkListSerializer' object is not iterable
Exception Location: /Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/site-packages/django/template/defaulttags.py in render, line 161
Python Executable: /Users/richardc/virtualenvs/rating_sytstem/bin/python
Python Version: 2.7.8
Python Path:
['/Volumes/Data/git/rating-system/rating_system_site',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python27.zip',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/plat-darwin',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/plat-mac',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/lib-tk',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/lib-old',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/lib-dynload',
'/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
'/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
'/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
'/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
'/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/richardc/virtualenvs/rating_sytstem/lib/python2.7/site-packages']
Server time: Thu, 12 Mar 2015 13:33:11 +1100
The line of code that throws the exception is in the django template library, and it is doing:
values=list(values)
The values
object is my serializer object:
Usage_Record_Serializer(context={u'view': <rating_system.views.rest.Usage_Record_ViewSet object>, u'request': <rest_framework.request.Request object>, u'format': None}, data=[{u'event_description': u'Test Event', u'event_value': 122, u'tags': u'PURCHAGES, VISA', u'reference_id': 20, u'external_service': 1, u'external_system': 2, u'external_service_key': u'Etx', u'event_date_time': u'2015-03-02T00:10:13.869285Z'}, {u'event_description': u'Test Event', u'event_value': 122, u'tags': u'PURCHAGES, VISA', u'reference_id': 21, u'external_service': 1, u'external_system': 2, u'external_service_key': u'Etx', u'event_date_time': u'2015-03-02T00:10:13.869285Z'}], many=True)
If I just browse to http://127.0.0.1:8000/usage_records/ again, the template renders correctly, with these new records included.
The basic code is:
class Usage_Record_Serializer(BulkSerializerMixin, serializers.ModelSerializer):
class Meta(object):
model = Usage_Record
list_serializer_class = BulkListSerializer
read_only_fields = ('id', 'upload_date_time',)
class Usage_Record_ViewSet(BulkModelViewSet):
queryset = Usage_Record.objects.all()
serializer_class = Usage_Record_Serializer
permission_classes = (permissions.IsAuthenticated,)
bulk_router.register(r'usage_records', rest.Usage_Record_ViewSet)
If I use postman or curl, no error is thrown ... so this does seem to be some bad interaction with the DRF api browser.
Any thoughts on why this happens?
Thanks,
Richard
Hi
Is there a way to have a list of items, and have them created or updated based on the existence of a PK?
Thanks
The README explains how to use the router as follows:
from rest_framework_bulk.routes import BulkRouter
class UserViewSet(BulkModelViewSet):
model = User
def allow_bulk_destroy(self, qs, filtered):
"""Don't forget to fine-grain this method"""
router = BulkRouter()
router.register(r'users', UserViewSet)
However, BulkModelViewSet is not imported, neither is it defined in the example.
Similarly, the example registers UserViewSet, while the example above defines FooView - IMO it would be helpful if the example stayed in context.
Without a test suite, it's difficult for me to understand how to actually use this. Could someone post a sample implementation for BulkUpdateAPIView?
I've added BulkSerializerMixin
to a view set (and set list_serializer_class
to BulkListSerializer
),
trying to PATCH a single object (which should not touch bulk operations at all), raises this error:
AttributeError: 'NoneType' object has no attribute 'request'
may be related to #39
using Django 1.10 with 3.4.6
Subj. What is the reason?
Guys, I am not able to raise the server due to this error after I have inserted the necessary classes for the use of Bulk.
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f8493c1d620>
Traceback (most recent call last):
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/utils/autoreload.py", line 225, in wrapper
fn(*args, **kwargs)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/core/management/commands/runserver.py", line 117, in inner_run
self.check(display_num_errors=True)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/core/management/base.py", line 379, in check
include_deployment_checks=include_deployment_checks,
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/core/management/base.py", line 366, in _run_checks
return checks.run_checks(**kwargs)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/core/checks/registry.py", line 71, in run_checks
new_errors = check(app_configs=app_configs)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/core/checks/urls.py", line 13, in check_url_config
return check_resolver(resolver)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/core/checks/urls.py", line 23, in check_resolver
return check_method()
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 396, in check
for pattern in self.url_patterns:
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/utils/functional.py", line 37, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 533, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/utils/functional.py", line 37, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/urls/resolvers.py", line 526, in urlconf_module
return import_module(self.urlconf_name)
File "/opt/rh/rh-python36/root/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/var/www/django/WebWhatsAppExploitServer/APICAMPAIGN/urls.py", line 19, in <module>
path('api/', include('bots_api.urls')),
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/django/urls/conf.py", line 34, in include
urlconf_module = import_module(urlconf_module)
File "/opt/rh/rh-python36/root/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/var/www/django/WebWhatsAppExploitServer/bots_api/urls.py", line 48, in <module>
path('',bulk_router.get_urls()),
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/rest_framework/routers.py", line 363, in get_urls
urls = super(DefaultRouter, self).get_urls()
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/rest_framework/routers.py", line 261, in get_urls
routes = self.get_routes(viewset)
File "/var/www/django/WebWhatsAppExploitServer/venv/lib64/python3.6/site-packages/rest_framework/routers.py", line 176, in get_routes
extra_actions = viewset.get_extra_actions()
AttributeError: type object 'ContactsViewSet' has no attribute 'get_extra_actions'
Here's a snippet of what I'm doing.
urlpatterns = [
path('api/', include('bots_api.urls')),
]
bulk_routes = [
('contacts/list', ContactsViewSet, 'Contacts List'),
('contacts/details', ContactsDetailsViewSet, 'Contacts List'),
('contacts/blacklist', ContactBlackListViewSet, 'Contacts Black List')
]
bulk_router = BulkRouter()
for route in bulk_routes:
bulk_router.register(route[0],route[1],route[2])
urlpatterns = [
path('',include(bulk_router.urls)),
]
class ContactsSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class Meta(object):
from bots_api.models import Contacts
model = Contacts
fields = ('__all__')
list_serializer_class = BulkListSerializer
class ContactsViewSet(ListBulkCreateUpdateDestroyAPIView):
from bots_api.lib.serializers.contacts import ContactsSerializer
serializer_class = ContactsSerializer
filter_backends = (filters.OrderingFilter,
filters.SearchFilter,
DjangoFilterBackend)
search_fields = ['phone_number', 'phone_region', 'phone_type', 'tag', 'created',
'updated']
def get_queryset(self):
contact_id = self.request.query_params.get('id', None)
client_id = self.request.query_params.get('client', None)
number = self.request.query_params.get('number', None)
active = self.request.query_params.get('active', None)
queryset = self.ContactsSerializer.Meta.Contacts.objects.all()
if contact_id:
queryset = queryset.filter(id=contact_id)
if client_id:
queryset = queryset.filter(client_id=client_id)
if number:
queryset = queryset.filter(phone_number__contains=number)
if not active is None:
queryset = queryset.filter(active=active)
return queryset
I've been having this problem since yesterday, does anyone know where I might be going wrong?
When trying to PATCH with a list of dicts, I'm getting this error:
ERROR: test_bulk_update (api.tests.test_api.test_api_listings_bulk.TestBulkOperationsOnListings)
----------------------------------------------------------------------
Traceback (most recent call last):
File "E:\Development\django_projects\api\api.git\api\tests\test_api\test_api_listings_bulk.py", line 92, in test_bulk_update
response = self.client.patch("/listings/all/", updated_listings, format="json")
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\test.py", line 315, in patch
path, data=data, format=format, content_type=content_type, **extra)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\test.py", line 220, in patch
return self.generic('PATCH', path, data, content_type, **extra)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\test.py", line 237, in generic
method, path, data, content_type, secure, **extra)
File "e:\Development\django_projects\api\lib\site-packages\django\test\client.py", line 416, in generic
return self.request(**r)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\test.py", line 288, in request
return super(APIClient, self).request(**kwargs)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\test.py", line 240, in request
request = super(APIRequestFactory, self).request(**kwargs)
File "e:\Development\django_projects\api\lib\site-packages\django\test\client.py", line 501, in request
six.reraise(*exc_info)
File "e:\Development\django_projects\api\lib\site-packages\django\utils\six.py", line 686, in reraise
raise value
File "e:\Development\django_projects\api\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "e:\Development\django_projects\api\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "e:\Development\django_projects\api\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "e:\Development\django_projects\api\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\viewsets.py", line 90, in view
return self.dispatch(request, *args, **kwargs)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\views.py", line 489, in dispatch
response = self.handle_exception(exc)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\views.py", line 449, in handle_exception
self.raise_uncaught_exception(exc)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\views.py", line 486, in dispatch
response = handler(request, *args, **kwargs)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework_bulk\drf3\mixins.py", line 79, in partial_bulk_update
return self.bulk_update(request, *args, **kwargs)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework_bulk\drf3\mixins.py", line 73, in bulk_update
serializer.is_valid(raise_exception=True)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\serializers.py", line 718, in is_valid
self._validated_data = self.run_validation(self.initial_data)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\serializers.py", line 596, in run_validation
value = self.to_internal_value(data)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\serializers.py", line 635, in to_internal_value
validated = self.child.run_validation(item)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\serializers.py", line 431, in run_validation
value = self.to_internal_value(data)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework_bulk\drf3\serializers.py", line 16, in to_internal_value
ret = super(BulkSerializerMixin, self).to_internal_value(data)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\serializers.py", line 461, in to_internal_value
validated_value = field.run_validation(primitive_value)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\fields.py", line 776, in run_validation
return super(CharField, self).run_validation(data)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\fields.py", line 524, in run_validation
self.run_validators(value)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\fields.py", line 538, in run_validators
validator(value)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\validators.py", line 81, in __call__
queryset = self.exclude_current_instance(queryset)
File "e:\Development\django_projects\api\lib\site-packages\rest_framework\validators.py", line 75, in exclude_current_instance
return queryset.exclude(pk=self.instance.pk)
AttributeError: 'QuerySet' object has no attribute 'pk'
Relevant code:
class ListingSerializer(BulkSerializerMixin, serializers.ModelSerializer):
slug = serializers.ReadOnlyField()
images = ListingImageSerializer(many=True, read_only=True)
class Meta:
model = Listing
list_serializer_class = BulkListSerializer
fields = '__all__'
class BaseListingViewSet(generics.BulkModelViewSet):
queryset = Listing.objects.all()
serializer_class = ListingSerializer
POSTing data works fine, by the way, it's only PATCH that generates this error.
I'm using
As above
Although the Bulk Actions are present in my project I haven't used them to their full potential yet.
I'm beginning my tests with bulk deletes. Mymodel
inherits from BulkModelViewSet
.
In my urls.py
file I define the URL used to interact with my model:
router.register(r"v1/mymodels", mymodels_views_v1.MyModelViewSet)
this allows me to GET, POST, PUT and DELETE on the URL:
www.my-api.com/v1/mymodels/{{mymodel_id}}
Can I use this same URL for bulk operations? If so, what is the correct syntax?
eg: www.my-api.com/v1/mymodels/[{{mymodel_id1}},{{mymodel_id2}}]
If not, what changes should I make?
Thanks
Hi, I have problems when I try to make bulk POST (with more than one objects) to django-rest-framework. Then I saw your project but again I don't have success, when I am trying to POST multiple objects I always receive AttributeError: 'list' object has no attribute 'get'
. I tried to fix it but without success and I made a repo with basic example of my project.
The repo is here and the request that I am trying is something like this (I am sending it from the django-rest web view)
[{
"name": "Some test name",
"degree": "-",
"short": "-",
"email": "[email protected]",
"department": "-"
},
{
"name": "Trugvai..",
"degree": "-",
"short": "-",
"email": "[email protected]",
"department": "-"
}]
Thanks!
Is there a reason that the BulkUpdateModelMixin does not have the same "check for bulk" switch that the BulkCreate does?
If not, would you mind a pull request to add it in?
Bulk PUT requests to my services are taking between 30 and 40 seconds to complete successfully. Bulk POST requests complete successfully in under 1 second. I've tried submitting various numbers of objects, between 1 and 20, using both methods and the response times don't seem to vary much.
Why do you think the PUTs are taking so long?
I'm using Python 3.4, Django 1.7, DRF 2.4.4, DRF-bulk 0.1.3, with PostgreSQL 9.3 and the default Django web development server on the backend.
Does this take advantage of Django's bulk_create method?
Maybe it's not a feature in DRF-bulk but rather some code around that lib user writes. Just thinking about it, what do you think ?
Can someone please answer this question of mine?
http://stackoverflow.com/questions/38265415/django-rest-framework-bulk-bulkupdateview-outuput-customization
I have a permisson class like this
from rest_framework import status, permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Custom permission to only allow owners of an object to edit it.
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
# Write permissions are only allowed to the owner of the snippet.
return obj.user == request.user
and my ViewSet:
class CompanyView(ListBulkCreateUpdateAPIView):
serializer_class = company_serializer.CompanySerializer
permission_classes = (IsOwnerOrReadOnly,)
But When I make a POST/PUT request to insert or update many records, My ViewSet does not use Permission class to check permissions.
How to add permission classes to Bulk ViewSet ?
The update method of a bulkSerializer is not working if the id is not of type string/unicode for example a bson.objectid.ObjectId
mine solution was to force the unicode type in the BulkListSerializer
class BulkListSerializer(ListSerializer):
update_lookup_field = 'id'
def update(self, queryset, all_validated_data):
id_attr = getattr(self.child.Meta, 'update_lookup_field', 'id')
all_validated_data_by_id = {
i.pop(id_attr): i
for i in all_validated_data
}
if not all((bool(i) and not inspect.isclass(i)
for i in all_validated_data_by_id.keys())):
raise ValidationError('')
# since this method is given a queryset which can have many
# model instances, first find all objects to update
# and only then update the models
objects_to_update = queryset.filter(**{
'{}__in'.format(id_attr): all_validated_data_by_id.keys(),
})
if len(all_validated_data_by_id) != objects_to_update.count():
raise ValidationError('Could not find all objects to update.')
updated_objects = []
for obj in objects_to_update:
obj_id = getattr(obj, id_attr)
#here
obj_validated_data = all_validated_data_by_id.get(unicode(obj_id))
# use model serializer to actually update the model
# in case that method is overwritten
updated_objects.append(self.child.update(obj, obj_validated_data))
return updated_objects
I think is not a "portable solution" but make the job for me.
Hello,
DRF has introduced some significant changes in some of the logic regarding the Serializer.
For example, there is no more pre_save
, but perform_create
and perform_update
instead that this package relies upon.
Another thing is request.DATA
that is being deprecated and serializer.object
that became serializer.validated_data
.
Is there a workkaround for the time being so that we could still use DRF 3.0 with DRF-bulk?
Thanks!
Hi,
I'm use Django 1.9 and DRF3.
I tried follow the tutorial to create my ListBulkCreateUpdateDestroyAPIView.
I had problem to register the route.
I changed to BulkModelViewSet and fix my problem.
Can you help me to user ListBulkCreateUpdateDestroyAPIView?
Could you shed any light on this? Thanks?
python 3.7.3
django 2.2.3
djangorestframework 3.9.4
djangorestframework-bulk 0.2.1
class Milestone(models.Model): project = models.ForeignKey(Project, on_delete=models.CASCADE) position = models.IntegerField(default=0) name = models.CharField(max_length=100, default='')
class MilestoneSerializer(BulkSerializerMixin, serializers.ModelSerializer): class Meta: model = Milestone fields = ['id','project', 'position', 'name',] list_serializer_class = BulkListSerializer
class MilestoneViewSet(BulkModelViewSet): queryset = Milestone.objects.all() serializer_class = MilestoneSerializer
work when posting one object:
data={'project':4,'position':21,'name':'test'}
but it does not work posting two objects:
data=[{'project':4,'position':21,'name':'test'},{'project':4,'position':22,'name':'test'}]
Can someone explain if it is a bug or I miss something ?
When creating, I have the need to validate the entire collection of items as a whole. For instance, there should be validation to ensure there are exactly three items present. At the moment, I do not see an easy way to accomplish this.
Hi
Is this necessary?
I recently ran into a circular import issue where drf-bulk imports drf which in turn imports some of our code(via DEFAULT_PAGINATION_CLASS in DRF) and it hid the actual error which occurred deep inside our code.
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x102470840>
Traceback (most recent call last):
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
self.check(display_num_errors=True)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/core/management/base.py", line 385, in check
include_deployment_checks=include_deployment_checks,
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/core/management/base.py", line 372, in _run_checks
return checks.run_checks(**kwargs)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/core/checks/registry.py", line 81, in run_checks
new_errors = check(app_configs=app_configs)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/core/checks/urls.py", line 14, in check_url_config
return check_resolver(resolver)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/core/checks/urls.py", line 24, in check_resolver
for pattern in resolver.url_patterns:
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/urls/resolvers.py", line 310, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/django/urls/resolvers.py", line 303, in urlconf_module
return import_module(self.urlconf_name)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/src/server/veundmint/veundmint/urls.py", line 33, in <module>
url(r'^', include(router.urls)),
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/rest_framework/routers.py", line 81, in urls
self._urls = self.get_urls()
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/rest_framework/routers.py", line 355, in get_urls
urls = super(DefaultRouter, self).get_urls()
File "/Users/n/Sites/VEUNDMINT_TUB_Brueckenkurs/venv/lib/python3.5/site-packages/rest_framework/routers.py", line 261, in get_urls
view = viewset.as_view(mapping, **route.initkwargs)
TypeError: as_view() takes 1 positional argument but 2 were given
My code is exactly like in the example in the README
# Routers provide an easy way of automatically determining the URL conf.
router = BulkRouter()
router.register(r'server-action', WebsiteActionViewSet)
router.register(r'score', ScoreViewSet, base_name='scores')
router.register(r'whoami', UserViewSet, base_name='whoami')
router.register(r'foo', FooViewSet)
urlpatterns = [
#url(r'^', include('veundmint_base.urls')),
url(r'^', include(router.urls)),
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api-token-auth/', obtain_jwt_token),
]
when I do
router.register(r'foo', FooViewSet.as_view(), base_name='foo')
The API endpoint foo/
is not available
It would be great to have a simple_app that also works in django 1.8 or restframework > 3
I'm trying to use the new bulk update that uses DRF 3. When I try to bulk update with a model that uses a unique_together
constraint I get an error: 'QuerySet' object has no attribute 'pk'
Here is the code
#the model
class Answer(models.Model):
user = models.ForeignKey(User, null=False, blank=False)
parameter = models.ForeignKey(Parameter, null=False, blank=False)
answer_number = models.FloatField(null=True, blank=True)
answer_date = models.DateField(null=True, blank=True)
answer_boolean = models.BooleanField(default=False)
answer_currency = models.DecimalField(null=True, blank=True, max_digits=24, decimal_places=8)
class Meta:
unique_together = ("user", "parameter")
#the serializer
class AnswerSerializer(BulkSerializerMixin, serializers.ModelSerializer):
answer = NoValidationField()
class Meta:
model = Answer
fields = ['id', 'answer', 'parameter', 'user']
list_serializer_class = BulkListSerializer
#the view
class AnswerList(ListBulkCreateUpdateAPIView):
queryset = Answer.objects.all()
serializer_class = AnswerSerializer
I tried to debug the problem and I think it is a validation problem. Plase help.
TY
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.