Skip to content

Commit

Permalink
Fix bug when using gcm serializer as a nested serializer.
Browse files Browse the repository at this point in the history
When the serializer is nested the unique validator on registration_id
does not behave correctly.  This is a known issue with DRF
see: encode/django-rest-framework#2403

Added missing allow_null to device_id field

Fixes jazzband#270
  • Loading branch information
jamaalscarlett committed Jan 21, 2016
1 parent dac05ab commit 038d7f9
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions push_notifications/api/rest_framework.py
Expand Up @@ -2,7 +2,6 @@

from rest_framework import permissions
from rest_framework.serializers import ModelSerializer, ValidationError
from rest_framework.validators import UniqueValidator
from rest_framework.viewsets import ModelViewSet
from rest_framework.fields import IntegerField

Expand All @@ -22,7 +21,7 @@ def to_internal_value(self, data):
# validate hex string and convert it to the unsigned
# integer representation for internal use
try:
data = int(data, 16)
data = int(data, 16) if type(data) != int else data
except ValueError:
raise ValidationError("Device ID is not a valid hex number")
return super(HexIntegerField, self).to_internal_value(data)
Expand All @@ -34,7 +33,7 @@ def to_representation(self, value):
# Serializers
class DeviceSerializerMixin(ModelSerializer):
class Meta:
fields = ("name", "registration_id", "device_id", "active", "date_created")
fields = ("id", "name", "registration_id", "device_id", "active", "date_created")
read_only_fields = ("date_created", )

# See https://github.com/tomchristie/django-rest-framework/issues/1101
Expand All @@ -59,29 +58,33 @@ def validate_registration_id(self, value):
class GCMDeviceSerializer(ModelSerializer):
device_id = HexIntegerField(
help_text="ANDROID_ID / TelephonyManager.getDeviceId() (e.g: 0x01)",
style={'input_type': 'text'},
required=False
style={"input_type": "text"},
required=False,
allow_null=True
)

class Meta(DeviceSerializerMixin.Meta):
model = GCMDevice

extra_kwargs = {
# Work around an issue with validating the uniqueness of
# registration ids of up to 4k
'registration_id': {
'validators': [
UniqueValidator(queryset=GCMDevice.objects.all())
]
}
}
extra_kwargs = {"id": {"read_only": False, "required": False}}

def validate_device_id(self, value):
# device ids are 64 bit unsigned values
if value > UNSIGNED_64BIT_INT_MAX_VALUE:
raise ValidationError("Device ID is out of range")
return value

def validate(self, attrs):
devices = None
if self.context["request"].method in ["PUT", "PATCH"]:
devices = GCMDevice.objects.filter(registration_id=attrs["registration_id"]) \
.exclude(id=attrs["id"])
elif self.context["request"].method == "POST":
devices = GCMDevice.objects.filter(registration_id=attrs["registration_id"])
if devices:
raise ValidationError("Registration ID must be unique")
return attrs


# Permissions
class IsOwner(permissions.BasePermission):
Expand Down

0 comments on commit 038d7f9

Please sign in to comment.