Skip to content

Corrected docs on router include with namespaces. #5843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 13, 2018

Conversation

carltongibson
Copy link
Collaborator

For Django 2.0 you MUST provide app_name when using namespace.

Closes #5659

@carltongibson carltongibson added this to the 3.8 Release milestone Feb 20, 2018
For Django 2.0 you MUST provide `app_name` when using `namespace`.

Closes encode#5659

Correct namespace reference

Updated example without changing old text.
Router URL patterns can also be included using _application_ and _instance_ namespaces.

To use an _application namespace_ pass a 2-tuple containing the `router.urls` and the app name.
To use an _instance namespace_ pass the optional `namespace` parameter.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we reference anywhere in the Django docs here? I wouldn't know the difference between the two off the top of my head.

I guess ideally we'd just say "Do X", and have "If you need to do Y then ..." slightly later in the docs, rather than presenting the developer with a choice that they need to make here.

Copy link
Collaborator Author

@carltongibson carltongibson Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The [URL namespaces docs] reference below is the canonical source. It's basically the only place it's ever discussed.

The other place we could link to is the include reference https://docs.djangoproject.com/en/2.0/ref/urls/#include

The way I thought about phrasing this is:

  1. Try to include via an app-level urls module, setting the app_name variable there. Basically never use the namespace parameter, you basically don't want it.
  2. If you MUST include the router urls directly (and need namespaces) then provide (router.urls, app_name) — that's what you want. (If you really need namespace then go-ahead, but you still have to pass the 2-tuple first.)

But by the time I'd drafted than I basically need to rewrite the Django docs (linked) so people should really read those.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The >80% case is to just pass the 2-tuple and ignore the namespace parameter. Let me re-phrase around that...

Copy link
Collaborator Author

@carltongibson carltongibson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @tomchristie.

I adjusted the phrasing. Have a look.

(It's tricky because the whole application vs instance thing isn't clearly represented by the API...)


urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^api/', include(router.urls, namespace='api')),
url(r'^api/', include((router.urls, 'app_name')),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the >80% usage for namespaces. (We want to namespace our URL names to a single application.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The include(( ... ) looks wrong to me?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by the app_name argument, does it have to match the app name, or is it a general purpose namespace?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parenthesis is missing. I'll fix that.

SO... 😃

What ultimately gets passed included is a 3-tuple:

(A_LIST_OF_PATTERNS, AN_APPLICATION_NAMESPACE, AN_INSTANCE_NAMESPACE)

In the example here we pass the first two of those, as a 2-tuple.

When you include a module the list of patterns comes from urlpatterns, and the application namespace comes from app_name.

I've just used app_name here as any old string. It's usually, 'admin', or 'polls' or 'rest_framework'.

In this example the instance namespace ends up being the same as the application namespace, because we didn't provide one. (This means that it'll be None if the application namespace is, which is just the global namespace we all start out with.)

But we could do provide, say, namespace='v1' and such.

Grrr. I'm still not happy here.

If using namespacing with hyperlinked serializers you'll also need to ensure that any `view_name` parameters on the serializers correctly reflect the namespace. In the example above you'd need to include a parameter such as `view_name='api:user-detail'` for serializer fields hyperlinked to the user detail view.
(`include` also allows an optional `namespace` parameter to also create an _instance namespace_.
This defaults to `None` and will be set to `app_name` if not provided.
See Django's [URL namespaces docs][url-namespace-docs] for more details.)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need to say this? Not sure...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks better!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and will be set to app_name ...

Grrrr. "...the same as the application namespace..." or such.

Don't merge this yet. I'll have a go over the weekend.

@@ -72,14 +72,21 @@ Alternatively you can use Django's `include` function, like so…
url(r'^', include(router.urls)),
]

Router URL patterns can also be namespaces.
To include the router URL patterns with an application namespace pass a
`(router.urls, 'app_name')` 2-tuple to `include`.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the '' around app_name here. Hopefully that works.

The option is something like (PATTERN_LIST, APP_NAME)

]

If using namespacing with hyperlinked serializers you'll also need to ensure that any `view_name` parameters on the serializers correctly reflect the namespace. In the example above you'd need to include a parameter such as `view_name='api:user-detail'` for serializer fields hyperlinked to the user detail view.
(You may additionally pass an optional `namespace` parameter to `include` to also
create an _instance namespace_. See Django's [URL namespaces docs][url-namespace-docs] for more details.)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe if I drop the whole "...if namespace=None bit... and just let people read the docs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. Although do let's reference Django's include docs here - I think that'd be helpful.

@carltongibson
Copy link
Collaborator Author

Hey @tomchristie. Can I ask you to pass your eyes over this again.

  • 8f821dc Gives both app and instance namespace examples and links to both parts of the Django docs. I think it's about as clear as can be (without it becoming an essay).
  • e274bcd adds a little emphasis to the idea that you probably don't need namespaces, which is relevant when you're using Hyperlinked.... I keep having the same conversation around that, so I just want to draw it out. (I don't think people would be using namespaces at all unless we showed them).

@carltongibson carltongibson merged commit 0da4617 into encode:master Mar 13, 2018
@carltongibson carltongibson deleted the 38/router-include-docs branch March 13, 2018 14:52
pchiquet pushed a commit to pchiquet/django-rest-framework that referenced this pull request Nov 17, 2020
* Provide both app and instance namespace examples
* Emphasise non-namespaced option
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants