Aamir Khan
Aamir Khan

Reputation: 3031

Can I have different root URLs in the same app?

In my DRF project, I have 2 apps, Users and Products. Products has 2 models: Category and Product. My root URL conf looks like this

api_urls = [
    path('users/', include('users.urls')),
    path('products/', include('products.urls'))
]

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(api_urls))
]

and the products.urls

urlpatterns = [
  path('', views.ProductListCreateAPIView.as_view())
]

I want my API scheme to be something like

/api/users/
/api/products/
/api/categories/

Right now, this works fine for the first two URLS, but obviously not the third, i.e. if I was to add

path('categories', views.CategoriesListCreateAPIView.as_view())

to my products.urls, the URL scheme would be

/api/products/categories/

My question is, is there someway to achieve the /api/categories/ objective without splitting off Category into its own app? I feel as if it's too insignificant to warrant having its own app and should be in the same app as Product. Obviously, I guess I could just import the views directly in the root URL conf but that doesn't feel like a 'clean' solution. Should I be thinking of creating a separate App for Category? The Product model has a foreign key relation with Category and to me, it feels as if 2 separate Apps would just be complicating things.

Upvotes: 2

Views: 1144

Answers (2)

Aamir Khan
Aamir Khan

Reputation: 3031

I ended up opting for the following approach: Instead of using a single urls.py in my Products app, I created a URL module inside the app and added two urlconfs in it, one for each of Category and Product.

#product/urls/producturls.py

urlpatterns = [
  path('', views.ProductListCreateAPIView.as_view())
]

#product/urls/categoryurls.py

urlpatterns = [
  path('', views.CategoryListCreateAPIView.as_view())
]

Then I include() both in my root urlconf

api_urls = [
    path('users/', include('users.urls')),
    path('products/', include('products.urls.producturls')),
    path('categories/', include('products.urls.categoryurls'))
]

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(api_urls))
]

Screenshot

Upvotes: 5

Daniel Roseman
Daniel Roseman

Reputation: 599856

First of all you need to recognise you have some conflicting requirements; you want to do something unusual (two separate root paths in the same app) but you also want to keep it "clean".

The cleanest solution I can think of is not to use a prefix at all when including the app urlconf, but set it within the file as you do for the api prefix. So:

path('', include('products.urls'))

then

product_patterns = [
  path('', views.ProductListCreateAPIView.as_view()),
  ...
]

urlpatterns = [
    path('categories', views.CategoriesListCreateAPIView.as_view()),
    path('products/', include(product_patterns)
]

Upvotes: 3

Related Questions