I have a a UserProfile model that has a OneToOne with a the 
django.contrib.auth User and looks something like this:

class UserProfile(BaseModel):
    # Authentication information
    email = models.OneToOneField(
        User, to_field='username', db_index=True, unique=True, 
related_name='profile', on_delete=models.CASCADE
    )

I have another model that has a relation to a UserProfile and looks 
something like this:

class Something(BaseModel):
    user = models.ForeignKey(
        'UserProfile', to_field='email', related_name='something', 
db_index=True, null=True, on_delete=models.SET_NULL,
    )

I have made a custom relational field that looks like this:

class UserProfileField(serializers.RelatedField):
    queryset = UserProfile.objects.all()

    def to_representation(self, value):
        return value.email.username

    def to_internal_value(self, data):
        try:
            return 
UserProfile.objects.get(email=User.objects.get(username=data))
        except (User.DoesNotExist, UserProfile.DoesNotExist):
            raise serializers.ValidationError("User '" + str(data) + "' 
does not exist.")

The serializer for Something looks like this:

class SomethingSerializer(serializers.ModelSerializer):
    user = UserProfileField(required=True)

    class Meta:
        model = Something

The idea here is that when sending a request to Something, you should be 
able to just do:
{
  "user": "[email protected]"
}

rather than:
{
  "user": {"email": "[email protected]"}
}

The good news is that this works, the bad news is that it is rife with race 
conditions and integrity errors, since the 
to_representation/to_internal_value checks aren't done atomically with the 
serializer save/create (and take long enough that during testing it's quite 
common to run into these race conditions).

Is there a more correct way of achieving that flat serializer 
representation, and is this a gross misuse of custom relational fields?

-- 
You received this message because you are subscribed to the Google Groups 
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to