Composite keys in Django Rest Framework?

2019-08-09 07:29发布

I've been working on a Django app for tracking VLAN usage in multiple network environments, which would be used by other apps to allocate VLANs for new installations.

The model is a hierarchy: Location->VLANPool->VLAN

So there is a unique VLAN 100 at each location, which could be a member of a different pool, depending on the location. Client applications can then say "give me the next VLAN in the customer_networks" pool, and then perform various operations on the resulting VLAN - reserve, rename/comment, release.

Each model has a auto-created 'id' primary key, but the user/API client really cares about either the name field (pools) or the VLAN ID (vlans).

I've got a basic REST API going with Django REST Framework, by creating a ModelViewSet and ModelSerializer for each model in my app and registering the ViewSets with a router. However, that uses the pk by default, which is meaningless to the end user. That's fine for the browsable API, where you can just click on results, but I'd like to be able to construct URLs without knowing about the database ID.

I like how little code I've had to write to get to where I am, but what is the minimum I need to change to get to an API schema like this:

/api/location/{location_name}
/api/location/{location_name}/pools
/api/location/{location_name}/pools/{pool_name}
/api/location/{location_name}/pools/{pool_name}/vlans
/api/location/{location_name}/vlans/{vlan_id}

That is, where the lookup key is a composite of the location.name and the actual object's name fields.

Can someone point me in the right direction? I guess I'll need to either change the queryset on the Serializer or create a new Serializer, but how about the URL construction?

I started out by adding lookup_field='name' to my ViewSets but then the router says it can't resolve URLs using the name instead of the id (using an ID instead gets a 404, so it is actually recognising the name as valid).

2条回答
Explosion°爆炸
2楼-- · 2019-08-09 07:39

You can generate the custom urls using the lookup_fields. Can you follow this link below here Multiple LookUp Args and Custom Urls.

查看更多
We Are One
3楼-- · 2019-08-09 07:57

The key phrase I was missing was "nested router" or "nested resource" - the VLANs are nested inside the location object. Thinking of the resources instead of the database makes this clearer.

This functionality is provided by both the drf-nested-routers and drf-extensions packages. I will be giving drf-extensions a try, since it seems a little more mature (no "this is WIP" banner at the top!).

查看更多
登录 后发表回答