HyperlinkedIdentityField to_internal_value with nested HyperlinkedModelSerializer #9968
Replies: 2 comments
|
Hi @JulienPalard , Since HyperlinkedIdentityField is technically a read-only field designed for representation, it doesn't handle the lookup logic needed to 'find' an existing object during a POST request. nstead of manually patching the queryset or overriding create in a horrible way, you can easily use drf-writable-nested library. This library is highly functional and useful for nested updates. In your specific case; from drf_writable_nested.serializers import WritableNestedModelSerializer
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ("url", "username")
# Ensure 'url' is not read_only if you want to use it for lookups
extra_kwargs = {'url': {'read_only': False}}
class TeamSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Team
fields = ("url", "name")
extra_kwargs = {'url': {'read_only': False}}
class MembershipSerializer(WritableNestedModelSerializer):
user = UserSerializer()
team = TeamSerializer()
class Meta:
model = Membership
fields = ("url", "user", "team")Does that make the code a little longer? Yes, but I think readability trumps everything else. |
It does. This: works, so the Also, drf-writable-nested looks designed to allow to updated the nested serializers. I don't want one to be able to update a team name VIA a PUT on |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hello world,
I have the following code:
The
UserSerializerandTeamSerializerare simpleHyperlinkedModelSerializerlike:What I want is to create new memberships by POSTing objects containing a pair of existing user and existing team, like:
{ "user": {"url":"http://localhost:8000/api/users/2/", "username": "a-teacher"}, "team": {"url":"http://localhost:8000/api/teams/2/", "name": "TeamOfTeacher"} }(I know what you think, and no I don't want to use
HyperlinkedRelatedFields, I really want nested serializers here. Because if I useHyperlinkedRelatedFieldsit would force clients to do 1+N HTTP requests to get a list of memberships with user names and team names. I want clients to be able to get a good view with a single HTTP request. Plus in real life I have a few more fields in the membership, user, and team objects that may be interesting to give at the first request).So I'm writing a
createmethod in theMembershipSerializerclass:But having to patch the
querysetin the HyperlinkedIndetityField just to haveto_internal_valueworking seems horrible.I could parse the URL myself, seems horrible too, knowing that
to_internal_valueexists.I could use the
usernameinstead of theurlto find the user back, but that seems horrible too, URI are things identifiers, let's use them?First, I don't understand why the
HyperlinkedModelSerializerdon't push the queryset itself to its auto-genratedurlfield, it could derive the queryset from the model as it have it, that would solve it all, am I right? I would be able to "just" write:which is nicer but still seems a bit "huge" to "just" get the user, I really feel like I'm missing something big and obvious, am I?
All reactions