0

Context

I have two viewsets, with their own routers to automatically generate the URLs from them :

  • ModelAViewset
  • ModelBViewset

For now, only the ModelAViewset details can be access through the following URL :

{root_url}/model-a/<slug>

With '<slug>' being the ModelA 'slug' field, as a lookup_field.

I am trying to figure out a way to build a route towards ModelBViewset detail as follows : {root_url}/model-a/<model_a_slug>/model-b/<model_b_pk>

Questions

  1. Is there a way to use a more explicit lookup_field value, dynamically based on the model name ? Like this : {root_url}/model-a/<model_a_slug>

Note : To keep it simple in the model, I would rather like to leave the 'slug' field name of ModelA as is

  1. Based on Viewsets and Routers, is there a way to access the ModelBViewset details through a multi lookup_fields ? With an URL like :

    {root_url}/model-a/<model_a_slug>/model-b/<model_b_pk>

Thanks, by advance

  • 1
    [`DRF nested routers`](https://github.com/alanjds/drf-nested-routers) can help you achieve the `{root_url}/model-a//model-b/` – Brian Destura Sep 02 '21 at 01:24
  • Thanks, indeed, I saw that yesterday. But there can't seem to be possible to use 'slug' instead of 'pk' as a lookup_field – William Afonso Sep 02 '21 at 07:35
  • In `ModelAViewset`, you can set `lookup_field = 'slug'` as described in the [`docs`](https://www.django-rest-framework.org/api-guide/generic-views/#attributes) to use the model field `slug` instead of `pk` – Brian Destura Sep 02 '21 at 07:47
  • And then when you use nested routers, you can do the same for `ModelBViewset`, so you can end up with `{root_url}/model-a//model-b/` – Brian Destura Sep 02 '21 at 07:48

1 Answers1

1

If you use the lookup_field on the model, the reference to this field will only work on the model where the lookup_field was defined.

That way, to work like this {root_url}/model-a/<model_a_slug>/model-b/<model_b_pk> you'll have to override ModelBViewset get_object function or you can follow this steps.

Another way to reference the slug field is to create it in the model itself as primary_key like this:

class ModelA(model.Model):

    slug = models.SlugField(
        max_length=60,
        unique=True,
        help_text="Define primary_key=true.",
        blank=True,
        primary_key=True
    )

That way, every time you're referencing an object in this model or other models like you want ({root_url}/model-a/<model_a_slug>/model-b/<model_b_pk>), you'll need to use the slug field and not id. The id field no longer exists.