How best to structure URLs in Django

I was wondering if I could get some advice on how to structure my URLs (and urls.py files!) in my Django project.

I’m building a relatively standard project that contains user profiles (i.e. a “public” display of a profile) and the user’s settings.

Ideally the profile would be accessed by:

website.com/profile/<slug:username>/
website.com/profile/<slug:username>/followers/
etc.

and settings…

website.com/settings/
website.com/settings/address/
etc.

Because almost all of the models, forms etc. are present in both sets of views, it feels like it makes sense for these to be handled within the same app in my project (“accounts”, “users” etc.). However feeding profile/ and settings/ to the same app-level urls.py file seems unworkable.

But If I split them into two apps, I’d have to import everything over from the original app into the new app to supply the view.

Option 1

One workaround that came to mind was to have two differently-named urls.py files in the same app, and include them separately in the project-level urls.py file.

project-level urls.py:

urlpatterns = [
    path('profile/', include('account.profile_urls')),
    path('settings/', include('account.settings_urls')),
]

Is this okay? I’ve not seen it done on any of the tutorials I’ve been working through.

Option 2

I guess the other thing to do is bite the bullet and rename the URLs so both can work together in a user-friendly way. Eg.

website.com/account/<slug:username>/
website.com/account/<slug:username>/followers/
website.com/account/settings/
website.com/account/settings/address/

But I’m reluctant to use non-desireable URLs just because it helps the app structure. Also I guess a user could change their username to “settings”! (Although I guess that’s handled with a restricted list).

On one hand using the URL schema to define the app structure feels wrong, as there’s lots of code that would have to be split off just because the URL says settings/ instead of profile/. But on the other hand using the app structure to dictate the URL schema feels just as weird because it should be as user-friendly as possible.

Surely there’s a way for both to be optimised without impacting the other? Is ‘Option 1’ a done thing?

Any help or advice greatly appreciated! Thanks

1 Like

Option 1 is perfectly ok. That the examples don’t explicitly demonstrate that idea, there’s nothing in the documentation saying that your urls file must be named urls.py. (In fact, see this example.)
You can also include another variable - what’s included doesn’t need to be a file reference. See the examples at Including url confs.

And if your URLs get really convoluted, there’s nothing saying that you can’t handle the entire URL yourself, where your view performs essentially the same functionality as Django’s URL resolver and you dispatch to the desired view. (I think it would need to be a really unique situation before you’d want to go that far.)

1 Like

Ah that’s great, thanks for confirming! I’ll go with option #1 and have two separate URL files to route the requests. Nice to know it’s so flexible (I hadn’t realised until now). I think I can actually go back and optimise some other URLs in other apps in a similar way.