estebistec / drf-compound-fields

Django-REST-framework serializer fields for compound types.
BSD 3-Clause "New" or "Revised" License
92 stars 12 forks source link

ListOrItemField(URLField()) does not accept lists #22

Open sbuss opened 9 years ago

sbuss commented 9 years ago

I was following the documentation, trying to integrate this into a new django-rest-framework-based project, but I ran into trouble trying to use ListOrItemField(serializers.URLField()). Namely, it never validates a list of URLs.

The documentation is correct when it comes to an item:

In [1]: from drf_compound_fields.fields import ListField
In [2]: from drf_compound_fields.fields import ListOrItemField
In [3]: from rest_framework import serializers
In [4]: class SkillsProfileSerializer(serializers.Serializer):
   ...:     name = serializers.CharField()
   ...:     skills = ListField(serializers.CharField(min_length=3))
   ...:     social_links = ListOrItemField(serializers.URLField())
   ...: 
In [5]: data = SkillsProfileSerializer({
   ...:     'name': 'John Smith',
   ...:     'skills': ['Python'],
   ...:     'social_links': 'http://chrp.com/johnsmith'
   ...: }).data
In [6]: sps = SkillsProfileSerializer(data=data)
In [7]: assert sps.is_valid(), sps.errors

But if you try to feed back in the serialized output of a list of URLs, it fails:

In [8]: data = SkillsProfileSerializer({
   ...:     'name': 'John Smith',
   ...:     'skills': ['Python'],
   ...:     'social_links': ['http://chrp.com/johnsmith', 'http://myface.com/johnsmith']
   ...: }).data
In [9]: data
Out[9]: {'name': u'John Smith', 'skills': [u'Python'], 'social_links': [u'http://chrp.com/johnsmith', u'http://myface.com/johnsmith']}
In [10]: sps = SkillsProfileSerializer(data=data)
In [11]: assert sps.is_valid(), sps.errors
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-10-6f75eb6cf39f> in <module>()
----> 1 assert sps.is_valid(), sps.errors

AssertionError: {'social_links': [u'Invalid value.']}

I haven't had time to implement a fix yet (trying to hit a deadline), but If you don't have time in the next couple days I should be able to loop back and figure out what's going wrong.

Note that that same data works fine for a ListField:

In [12]: data
Out[12]: {'name': u'John Smith', 'skills': [u'Python'], 'social_links': [u'http://chrp.com/johnsmith', u'http://myface.com/johnsmith']}
In [13]: class SkillsProfileSerializer(serializers.Serializer):
   ...:     name = serializers.CharField()
   ...:     skills = ListField(serializers.CharField(min_length=3))
   ...:     social_links = ListField(serializers.URLField())
   ...: 
In [14]: sps = SkillsProfileSerializer(data=data)
In [15]: assert sps.is_valid(), sps.errors
estebistec commented 9 years ago

I'm not sure I'll get to it that quick, but I'll try to.

The first think I'll be looking at is whether the issue in #20 is related. Over there, I wasn't properly passing options to the internal ListField of a ListOrItemField and so not all of the options took effect.

estebistec commented 9 years ago

@sbuss How important is it for you that this be fixed for compatibility with rest-framework 2.X, as opposed to when I upgrade this for rest-framework 3.0 (hopefully soon)?

estebistec commented 9 years ago

Please see #27