New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
With DRF 3.3.x, validated_data have boolean to False by default #3811
Comments
It's a bit strange that you seem to have errors inside the validated_data. |
Yes, I let DRF invokes it. This is my view: class MemberDetailAPI(RetrieveUpdateAPIView):
queryset = Profile.objects.all()
lookup_field = 'user__id'
obj_key_func = DetailKeyConstructor()
@etag(obj_key_func)
@cache_response(key_func=obj_key_func)
def get(self, request, *args, **kwargs):
# Code ...
@etag(obj_key_func, rebuild_after_method_evaluation=True)
def put(self, request, *args, **kwargs):
self.permission_classes = (IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)
return self.update(request, *args, **kwargs)
def get_serializer_class(self):
if self.request.method == 'GET':
return ProfileDetailSerializer
elif self.request.method == 'PUT':
return ProfileValidatorSerializer |
This seems to be linked to #2776. Do you force the content type to json in you tests ? |
Maybe a side effect?
Nope, the complete test case is: def setUp(self):
self.client = APIClient()
self.profile = ProfileFactory()
client_oauth2 = create_oauth2_client(self.profile.user)
self.client_authenticated = APIClient()
authenticate_client(self.client_authenticated, client_oauth2, self.profile.user.username, 'hostel77')
caches[extensions_api_settings.DEFAULT_USE_CACHE].clear()
def test_update_member_details_without_any_change(self):
"""
Updates a member but without any changes.
"""
response = self.client_authenticated.put(reverse('api-member-detail', args=[self.profile.user.id]))
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.profile.user.id, response.data.get('id'))
self.assertEqual(self.profile.user.username, response.data.get('username'))
self.assertEqual(self.profile.user.email, response.data.get('email'))
self.assertEqual(self.profile.user.is_active, response.data.get('is_active'))
self.assertIsNotNone(response.data.get('date_joined'))
self.assertEqual(self.profile.site, response.data.get('site'))
self.assertEqual(self.profile.avatar_url, response.data.get('avatar_url'))
self.assertEqual(self.profile.biography, response.data.get('biography'))
self.assertEqual(self.profile.sign, response.data.get('sign'))
self.assertFalse(response.data.get('show_email'))
self.assertEqual(self.profile.show_sign, response.data.get('show_sign'))
self.assertEqual(self.profile.hover_or_click, response.data.get('hover_or_click'))
self.assertEqual(self.profile.email_for_answer, response.data.get('email_for_answer')) The content type doesn't seem forced. |
So since you're not enforcing JSON, HTML is used. This limitation also applies to Django's Your options:
|
Maybe you have closed a little bit too fast my issue. I checked global settings and I force well JSON: REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'zds.api.pagination.DefaultPagination',
# Active OAuth2 authentication.
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
#'rest_framework.parsers.XMLParser',
'rest_framework_xml.parsers.XMLParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
#'rest_framework.renderers.XMLRenderer',
'rest_framework_xml.renderers.XMLRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'anon': '60/hour',
'user': '2000/hour'
},
'TEST_REQUEST_DEFAULT_FORMAT': 'json'
} |
Indeed. |
I don't know if it is useful but I inspected a bit and when I'm at this line with a def is_html_input(dictionary):
# MultiDict type datastructures are used to represent HTML form input,
# which may have more than one value for each key.
return hasattr(dictionary, 'getlist') Edit: |
Looks like a sideeffect of this issue's fix #3314 |
Does not reproduce on master. Either has been resolved, or else the test case was erroneously not sending JSON requests as expected (eg. different settings were actually in use). The later seems likely as this does describe the HTML form behaviour. Happy to reconsider if anyone can raise a reproducible case. |
There's nothing to check, that's how the booleans in HTML form work in the HTML specs: no value means False value. |
This is similar to this issue: #1101 |
Hi,
I have a very simple test case in my open source project where I checked that when I make a PUT request on a profile without any parameter, all fields keep their values.
Unfortunately, I upgraded my dependency of DRF from the version 3.1.1 and with the latest version,
validated_data
is no more empty when we don't specify any parameter so we update fields of our profile.We should keep nothing in
validated_data
Test case:
Serializer:
validated_data value with DRF 3.3.x:
validated_data value with DRF 3.1.1:
The text was updated successfully, but these errors were encountered: