pythondjangoresturlname-clash

Same model names in Django's project


I have a project with two apps:

In accounts app I am using Django's Group model (for account permissions) and in classes app I have another one model with the name Group (but it should be interpreted as a group of students).

My url.py looks like:

(...)
from rest_framework import routers
from .accounts import views as accounts_views
from .classes import views as classes_views

router = routers.DefaultRouter()
(...)
router.register(r"groups", accounts_views.GroupViewSet)
router.register(r"classes/groups", classes_views.GroupViewSet)
(...)

But it is not working as expected. /api page looks as follows:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    (...)
    "groups": "http://127.0.0.1:8000/api/classes/groups/",
    "classes/groups": "http://127.0.0.1:8000/api/classes/groups/",
    (...)
}

So, both targets the same address what is not what I want. Admin page works well (I can edit account's Group and classes's Group).

Any suggestions?

Edit:

Changing one of url.py's line as below (as suggested in one of answers below):

router.register(r"classes_groups", classes_views.GroupViewSet)

changes /api page to:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    (...)
    "groups": "http://127.0.0.1:8000/api/classes_groups/",
    "classes/groups": "http://127.0.0.1:8000/api/classes_groups/",
    (...)
}

So @argaen solution generally is not a solution for this case.


Solution

  • The url's name defaults to the lowercased model name, which in this case is 'group' for both viewsets. Thus, reverse cannot tell the difference and returns the first match for both.

    I believe passing an explicit basename to at least one of the urls should fix it:

    router = routers.DefaultRouter()
    (...)
    router.register(r"groups", accounts_views.GroupViewSet)
    router.register(r"classes/groups", classes_views.GroupViewSet, "classes_group")
    (...)