Should AdminSite be able to handle different namespace?

400 views
Skip to first unread message

Vajrasky Kok

unread,
Nov 9, 2013, 10:47:35 AM11/9/13
to django-d...@googlegroups.com
Greetings, friends!

This is related with this ticket: https://code.djangoproject.com/ticket/21132

While working on this ticket, I was pondering whether we should really fix this or not because one of the core developers said,

"The whole admin is currently built on the idea that the app is named admin, I think we should just deprecate the app_name argument."

Assuming his/her opinion is valid, my question is "What is the point of fixing something that we would deprecate in a short time?"

Would it be better if we just raise error if someone provided keyword `app_name` argument in AdminSite constructor? This would not break backward-incompatibility because this bug had prevented someone to provide keyword `app_name` anyway.

Thoughts? Of course, it is a different story, if we need to embrace `app_name` keyword argument gleefully.

Cheers,
Vajrasky

Florian Apolloner

unread,
Nov 9, 2013, 12:10:00 PM11/9/13
to django-d...@googlegroups.com
Hi Vajrasky,


On Saturday, November 9, 2013 4:47:35 PM UTC+1, Vajrasky Kok wrote:
While working on this ticket, I was pondering whether we should really fix this or not because one of the core developers said,

Imo fixing this won't be easy; see for instance how admin_urlname filter is implemented; we'd have a hard time passing anything else in there…
 
"What is the point of fixing something that we would deprecate in a short time?"

Not much.

Would it be better if we just raise error if someone provided keyword `app_name` argument in AdminSite constructor? This would not break backward-incompatibility because this bug had prevented someone to provide keyword `app_name` anyway.

Since it's already broken anyways we can just remove it instead of raising an error.

Cheers,
Florian

Russell Keith-Magee

unread,
Nov 9, 2013, 5:34:53 PM11/9/13
to Django Developers
On Sun, Nov 10, 2013 at 1:10 AM, Florian Apolloner <f.apo...@gmail.com> wrote:
Hi Vajrasky,


On Saturday, November 9, 2013 4:47:35 PM UTC+1, Vajrasky Kok wrote:
While working on this ticket, I was pondering whether we should really fix this or not because one of the core developers said,

Imo fixing this won't be easy; see for instance how admin_urlname filter is implemented; we'd have a hard time passing anything else in there… 
"What is the point of fixing something that we would deprecate in a short time?"

Not much.

I'm a little concerned about this talk about deprecation here -- the app_name exists for a reason, and at time the app_name feature was added, it worked (to the best of my knowledge, anyway). 
 
Would it be better if we just raise error if someone provided keyword `app_name` argument in AdminSite constructor? This would not break backward-incompatibility because this bug had prevented someone to provide keyword `app_name` anyway.

Since it's already broken anyways we can just remove it instead of raising an error.

Erm… or we can fix it. Like I said, it worked when I put it in. If it's been broken subsequently, that strikes me as a bug in the fix, not in the original idea.

I'm -1 on deprecating this unless someone can make a good argument for why the underlying concept is somehow flawed, and I'm not convinced it is (since it was working before).

Yours,
Russ Magee %-)
 

Florian Apolloner

unread,
Nov 10, 2013, 6:47:25 AM11/10/13
to django-d...@googlegroups.com
Hi Russ,


On Saturday, November 9, 2013 11:34:53 PM UTC+1, Russell Keith-Magee wrote:
I'm a little concerned about this talk about deprecation here -- the app_name exists for a reason, and at time the app_name feature was added, it worked (to the best of my knowledge, anyway). 

It most likely did, till we switched the admin to not use hardcoded URLs: https://github.com/django/django/commit/aaf77c1676e44019abe544911ff7a06eb2690295 -- I have to say that I completely missed app_name there since the tests didn't seem to cover it and URL namespaces had been kind of a blackbox to me. That said; we changed this two years ago, so my question is: is this a feature we want to have? Also I'd appreciate if you can come up with a few ideas of how to fix it and probably explain the rationale for adding it in the first place so I can understand how this was ment to be used.

Cheers,
Florian

Russell Keith-Magee

unread,
Nov 12, 2013, 8:16:13 PM11/12/13
to Django Developers
The use case was simple -- deploy two instances of admin in a single project. For example, you might have a truly 'access-all-areas' admin, and a cut down/modified admin for trusted editors that has specially customised workflows, etc. Admin has been specifically designed to allow this, and it's a documented feature [1].


Is this a feature we want? Well, I've never used it myself; and the fact that nobody has complained until now suggests that it's not especially well used. On the broader conceptual point, I see value in being able to isolate deployments of a block of URLs… but again, I can't say this is something I'm using.

As for how to fix it -- that's a bigger question. It's been a while since I spelunked in that particular code, so I'd need to go digging to offer an opinion.

Russ %- )

Florian Apolloner

unread,
Nov 13, 2013, 7:06:50 AM11/13/13
to django-d...@googlegroups.com
Hi Russ,


On Wednesday, November 13, 2013 2:16:13 AM UTC+1, Russell Keith-Magee wrote:
The use case was simple -- deploy two instances of admin in a single project. For example, you might have a truly 'access-all-areas' admin, and a cut down/modified admin for trusted editors that has specially customised workflows, etc. Admin has been specifically designed to allow this, and it's a documented feature [1].

This is something which can be done currently by supplying the name argument to the AdminSite [1] (this changes the instance namespace name for the urlconf). But we also have a lesser known (and not working) feature where you can also modify the app_name itself [2] -- which is causing problems here (application namespace vs instance namespace). I am not sure what app_name provides aside from more complexity :)

Cheers,
Florian

[1] https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.AdminSite
[2] https://github.com/django/django/blob/master/django/contrib/admin/sites.py#L55

German Larrain

unread,
Nov 13, 2013, 7:55:13 PM11/13/13
to django-d...@googlegroups.com
Hi guys

I must say I hit this issue a few months ago (I have more than one admin app living side by side). It was confusing, when reversing a URL name, whether to change 'admin' in a string like this `'admin:%s_%s_change'`, or use `current_app=self.admin_site.name`.

Since I don't like hardcoded strings and I (or someone using my code) would probably get confused over this at a later point, I created a utility function that perhaps may be useful for someone else and/or to clarify the problem:

def get_admin_view_url_name(model, view, admin_site=None):
admin_site = admin_site or 'admin'

# TODO: replace `module_name` with `model_name` when using Django 1.6
return '%s:%s_%s_%s' % (
admin_site,
model._meta.app_label,
model._meta.module_name,
view)

Just my 2 cents.

Germán

Florian Apolloner

unread,
Nov 14, 2013, 5:45:39 AM11/14/13
to django-d...@googlegroups.com
Hi Germán,

in your case you should be using current_app; then using reverse('admin:bla') will tell the urlresolver to reverse an admin url bla for an AdminSite with name == current_app -- this will also work in templates; which is good since you really don't want to change string there… When you need to refer to the "other" admin just pass current_app='other_admin' to reverse.

Chers,
Florian

German Larrain

unread,
Nov 14, 2013, 6:32:51 AM11/14/13
to django-d...@googlegroups.com
Hi Florian

I used to do that (pass `current_app='other_admin'` to reverse) and it worked fine until I hit a bump road (sorry, can't remember which) where I couldn't reverse to the admin site that I wanted by using `current_app` (it reversed to the "main" one if the URL name existed else raised a NoReverseMatch). And reading the docs again:

AdminSite instances take a single argument to their constructor, their name, which can be anything you like. This argument becomes the prefix to the URL names for the purposes of reversing them. This is only necessary if you are using more than one AdminSite.

So the name of the "other admin" becomes the prefix to the URL names for the purpose of reversing them.

Now I'm more confused.

Florian Apolloner

unread,
Nov 14, 2013, 6:47:31 AM11/14/13
to django-d...@googlegroups.com


On Thursday, November 14, 2013 12:32:51 PM UTC+1, German Larrain wrote:
So the name of the "other admin" becomes the prefix to the URL names for the purpose of reversing them.

Not prefix, the prefix is usually always "admin:", since that's the application namespace; what you should specify is the instance namespace and that one is reversed (usually) via current_app
 
Now I'm more confused.

Yeah, url namespaces are somewhat confusing :/

Florian Apolloner

unread,
Nov 14, 2013, 6:48:06 AM11/14/13
to django-d...@googlegroups.com
We might have to fix the docs there :)

Amirouche Boubekki

unread,
Nov 14, 2013, 10:55:32 AM11/14/13
to django-d...@googlegroups.com



2013/11/14 Florian Apolloner <f.apo...@gmail.com>

We might have to fix the docs there :)

It's was fixed somewhat [1]. The original parameter names were confusing:


url(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),

Both namespace and app_name are namespaces. The tuple argument is easier to understand:

(<patterns object>, <application namespace>, <instance namespace>)

It is still confusing because there is no real notion of application in Django, there is no application object or class. Instead we manipulate the application through its url patterns or in the point of view of the project partial urls.

What we actually do here, is include a list of partial urls that are probably linked to other applications or in the simple case to views. This list of partial urls has a name, its the application namespace parameter. In theory, it should be set by the application developper but in pratice the application_namespace is given the the application user. Why? Because then it would allow to create an ecosystem of generic application that are interoperable. So, AFAIK application_namespace use is application interoperability. I mean, that you can replace one admin application by another and reference the url the admin throught its application namespace which is 'admin'. I don't know if it's True in pratice. It's still possible to have this done, in applications through a lambda for instance:

include_admin_next = lambda instance_name: include(('adminnext.urls', 'admin', instance_name))

Thereafter, the instance_name or instance_namespace is more obvious, it allows to distinguish between several existence/presence of the list of partial urls in the project url tree.

I think most people will only want to use instance namespace anyway. Because there is no ecosystem of compatible application except in the admin space.

There is a good reason for the existence of both namespaces.

What I think can solve the problem is to rename the parameters of the first way to include urls with include to use the names used in the tuple notation (second include notation).

The more involving way, would be to have Application objects. I think someone is working on it but I'm not sure of the progress. I'm not sure about what follow, but in my opinion getting applications objects would also mean getting application tree properly working, dependencies properly working which basicly means, an instance of an application can be hooked several time in a project but it can need only one database load, or not. it depends of the application...

I'm not sure it answers your doubts, I hope it helps.


Good Luck

--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/87b88e75-8110-4136-acd2-77408f0fe5d3%40googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

German Larrain

unread,
Nov 22, 2013, 8:18:03 AM11/22/13
to django-d...@googlegroups.com
On Thursday, November 14, 2013 12:55:32 PM UTC-3, Amirouche Boubekki wrote:
2013/11/14 Florian Apolloner <f.apo...@gmail.com>
We might have to fix the docs there :)

It's was fixed somewhat [1]. ...
 
 
I think Florian refers to other part, which is indeed wrong. I just submitted a ticket with patch for that.

Tino de Bruijn

unread,
Nov 22, 2013, 8:22:45 AM11/22/13
to django-d...@googlegroups.com
Hmm, I still find it confusing. I have used namespaced urls when making a reusable app, by using reverse('<mycoolappname>:<urlname>"), but that does enforce someone to use the correct application namespace when including my app. I think this look more logical than prefixing all my urlnames with '<mycoolappname>_'. Is this the right usage?

Tino


--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.

German Larrain

unread,
Nov 22, 2013, 8:38:00 AM11/22/13
to django-d...@googlegroups.com
I had the same confusion that you seem to have. There is a difference between application namespace and instance namespace. Because usually you only have one instance of each of the installed apps, you don't need to pass `current_app=mycoolappname_instanceX`.

In the case of multiple admin instances, the application namespace (which is the argument `app_name` to the constructor of AdminSite, and the original topic of this post) will be 'admin' for all of them, thus the necessity to differentiate to which instance you wish to reverse a URL name by passing 'current_app' to the reverse function. Nonetheless, if none is given, the reverse will still work and will default to the first urlconf that matches the corresponding application namespace.

Tim Graham

unread,
Aug 13, 2014, 3:33:33 PM8/13/14
to django-d...@googlegroups.com
I looked into this today and couldn't see why you'd want to have a different `app_name`. In fact doing so would conflict with the docs: "Every instance of a single application will have the same application namespace. For example, Django’s admin application has the somewhat predictable application namespace of'admin'."

You can deploy multiple instances of the admin site using AdminSite(name='admin2') (this controls the "instance namespace"). This works fine, but if you try to specify a different `app_name`, you'll get broken behavior as described
on the ticket. I've submitted a PR (linked from the ticket) to remove it.

Tim Graham

unread,
Aug 22, 2014, 7:22:02 PM8/22/14
to django-d...@googlegroups.com
For those confused about namespaces, I have tried to expand and clarify the documentation: https://github.com/django/django/pull/3092

Please give it a read and add your questions there and I'll do my best to answer them (with the caveat that you could include me in those who found the topic confusing before I worked on this).
Reply all
Reply to author
Forward
0 new messages