apps with the same name

219 views
Skip to first unread message

Joseph Kocherhans

unread,
Jan 13, 2006, 6:49:22 PM1/13/06
to django-d...@googlegroups.com
In magic-removal, the admin interface allows for apps with the same
names to coexist as long as they are in separate packages. Admin urls
are now like /admin/mypackage/myapp/mymodel rather than just
/admin/myapp/mymodel.

Unfortunately, this doesn't work quite like I'd expect it to. Here's
what I can think of that's "broken":

Table names are still just appname_modelname. Of course you can use
'db_table' to fix the issue, but it seems like something that should
"just work (tm)" I don't really like the idea of prefixing the package
name, but I don't see any other obvious options. Ideas?

If I run:
./manage sql auth (or any other command that takes app_label as the first arg)
I get the sql for the first auth app that appears in INSTALLED_APPS.
AFAICT it's impossible to install the second app without switching
their order in settings.py. That's simply not acceptable.

I imagine there's a similar problem with the filesystem template loader.

If apps with duplicate names aren't *really* going to work, then I
think the admin urls should change back. Breadcrumbs and admin urls
were a lot less complicated before the change.

In short, I think it would be cool to allow apps with the same name to
be installed, and I think Django will take some criticism eventually
if it doesn't (especially if a buch of 3rd party apps are available),
but it doesn't really work now, and needs to be thought through.

Any ideas that don't involve 50+ character table names and 10 level
deep template directories? ;-)

Joseph

Max Battcher

unread,
Jan 14, 2006, 4:13:04 AM1/14/06
to django-d...@googlegroups.com
Joseph Kocherhans wrote:
> Any ideas that don't involve 50+ character table names and 10 level
> deep template directories? ;-)

What about application relabeling? Just like you might do a python
``import something as somebettername`` when there are conflicts across
namespaces or you just want something nicer in your actual code, you
could just add an "as" option to INSTALLED_APPS to specify an app name.

--
--Max Battcher--
http://www.worldmaker.net/

Amit Upadhyay

unread,
Jan 14, 2006, 4:32:31 AM1/14/06
to django-d...@googlegroups.com
On 1/14/06, Max Battcher <m...@worldmaker.net> wrote:

Joseph Kocherhans wrote:
> Any ideas that don't involve 50+ character table names and 10 level
> deep template directories? ;-)

What about application relabeling?  Just like you might do a python
``import something as somebettername`` when there are conflicts across
namespaces or you just want something nicer in your actual code, you
could just add an "as" option to INSTALLED_APPS to specify an app name.

Very cool idea. This can solve the problem of table names and keeps admin urls simpler. But templates is still something you have to worry about, and one solution is to keep a module name based structure in template directory, but a better solution could be to make template system aware of the current app, let it query django to find the "as" name name, and use that as a prefix to all template paths.

And ofcourse django-admin.py may contain a "rename app" command,  just in case you later changed your mind about their name which renames all the tables in the database, as well as all the matching subfolders in all template directories.

--
Amit Upadhyay
Blog: http://www.rootshell.be/~upadhyay
+91-9867-359-701

Adrian Holovaty

unread,
Jan 17, 2006, 12:27:33 PM1/17/06
to django-d...@googlegroups.com
On 1/14/06, Max Battcher <m...@worldmaker.net> wrote:
> Joseph Kocherhans wrote:
> > Any ideas that don't involve 50+ character table names and 10 level
> > deep template directories? ;-)
>
> What about application relabeling? Just like you might do a python
> ``import something as somebettername`` when there are conflicts across
> namespaces or you just want something nicer in your actual code, you
> could just add an "as" option to INSTALLED_APPS to specify an app name.

This is a pretty nice idea. How would the syntax look in INSTALLED_APPS?

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com | chicagocrime.org

Joseph Kocherhans

unread,
Jan 17, 2006, 6:54:09 PM1/17/06
to django-d...@googlegroups.com
On 1/17/06, Adrian Holovaty <holo...@gmail.com> wrote:
>
> On 1/14/06, Max Battcher <m...@worldmaker.net> wrote:
> > Joseph Kocherhans wrote:
> > > Any ideas that don't involve 50+ character table names and 10 level
> > > deep template directories? ;-)
> >
> > What about application relabeling? Just like you might do a python
> > ``import something as somebettername`` when there are conflicts across
> > namespaces or you just want something nicer in your actual code, you
> > could just add an "as" option to INSTALLED_APPS to specify an app name.
>
> This is a pretty nice idea. How would the syntax look in INSTALLED_APPS?

The most obvious options I see are:

INSTALLED_APPS = (
'django.contrib.admin',
'myapp.admin as myadmin',
)

or use tuples (or maybe dicts) like:

INSTALLED_APPS = (
('django.contrib.admin', 'admin'),
('myapp.admin', 'myadmin'),
)

I don't really like the second option (too much extra typing for the
simple and most often used case), but the first option feels kind of
magical. I guess another option would be to allow a combination of
strings and tupes like:

INSTALLED_APPS = (
'django.contrib.admin',
('myapp.admin', 'myadmin'),
)

The new django.conf.settings object could "do the right thing (tm)"
depending on the type. This option seems like it might be confusing
for people though.

Out of the 3 I think I like 'myapp.admin as myadmin' the best.
Preferences? Other options?

Joseph

Max Battcher / WorldMaker

unread,
Jan 17, 2006, 7:00:04 PM1/17/06
to Django developers
I was thinking that another option would be to decouple the
INSTALLED_APPS setting from the data store to allow for future changes
(such as a better place to store app-specific settings than the global
namespace as CAPS_NAMES in the settings file), similar to the
patterns() and include() functions of URLconf. Something like:

INSTALLED_APPS = (
app('django.contrib.admin'),
app('myapp.admin', as_='myadmin'),
)

Like I said, this could allow for future compatibility with things like
static_url= or other application-specific settings.

Russell Keith-Magee

unread,
Jan 17, 2006, 7:24:20 PM1/17/06
to django-d...@googlegroups.com
On 1/18/06, Joseph Kocherhans <jkoch...@gmail.com> wrote:
> This is a pretty nice idea. How would the syntax look in INSTALLED_APPS?

INSTALLED_APPS = (
    'django.contrib.admin',
    ('myapp.admin', 'myadmin'),
)

I'm +1 on this one; Existing behaviour is unaffected, new behaviour makes sense without being completely obscure.

+0 to the use of tuples across the board, and -0 on the use of an AS keyword in the string.

Another option would be to allow a dictionary for INSTALLED_APPS:

INSTALLED_APPS = {
    'admin': 'django.contrib.admin ',
    'myadmin': 'myapp.admin'
}

but this requires explicit naming of all apps (possibly a good thing - the 'pick the last name in the namespace' approach always struck me as slightly magical). Alternatively (or in addition), use a tuple on the None key for apps that you want to use the 'default' name:

INSTALLED_APPS = {
    None: ('django.contrib.admin', 'myadmin.otherapp')
    'myadmin': 'myapp.admin'
}

would yield admin, otherapp and myadmin applications. Either way, the existing behaviour of a list/tuple could be preserved in addition to this dictionary syntax, with Django doing the right thing as appropriate.

Russ Magee %-)

Joseph Kocherhans

unread,
Jan 18, 2006, 4:03:24 PM1/18/06
to django-d...@googlegroups.com
On 1/17/06, Russell Keith-Magee <freakb...@gmail.com> wrote:
>
> Another option would be to allow a dictionary for INSTALLED_APPS:
>
> INSTALLED_APPS = {
> 'admin': 'django.contrib.admin ',
> 'myadmin': 'myapp.admin'
> }

I think I like this option the best so far. It's very explicit, and
looks a lot cleaner than a bunch of tuples. I don't think requiring
the app name to be explicit is too high of a price. Adding things to
INSTALLED_APPS is a rare enough event that a few keystrokes probably
won't matter much. (It certainly isn't a big deal for me anyhow.) This
way we don't have to describe the rules for calculating the app name
either.

Any preferences Adrian? There are a few bugs in django.contrib.admin
I'd like to fix (history for example), but this ought to be done
first....

Assuming this change, admin urls should change back to myapp/mymodel,
and the breadcrumbs should be simplified as well.

Also, I think maybe the app_directories template loader ought to be
changed to take templates straight from myapp/templates rather than
myapp/templates/myapp. This gets rid of one extra level of hierarchy,
and allows a user to install a 3rd party app using a different name
without having to change the directory name in the app.

This *would* disallow people from overriding the admin templates in
their app, they'd have to do it in their project or whatever by using
the filesystem template loader. I consider this a good thing though as
it makes it impossible for two apps to override the same admin
template, thus, there's no question as to which one gets used.

The filesystem loader should use the overriden app name in calculating
template directory names.

There are certainly going to be a few more issues with templates, but
I think I'd need to dig in to the code more to figure them all out.

Joseph

Adrian Holovaty

unread,
Jan 18, 2006, 4:18:10 PM1/18/06
to django-d...@googlegroups.com
On 1/18/06, Joseph Kocherhans <jkoch...@gmail.com> wrote:
> > INSTALLED_APPS = {
> > 'admin': 'django.contrib.admin ',
> > 'myadmin': 'myapp.admin'
> > }
>
> I think I like this option the best so far. It's very explicit, and
> looks a lot cleaner than a bunch of tuples. I don't think requiring
> the app name to be explicit is too high of a price. Adding things to
> INSTALLED_APPS is a rare enough event that a few keystrokes probably
> won't matter much. (It certainly isn't a big deal for me anyhow.) This
> way we don't have to describe the rules for calculating the app name
> either.

Looks like a good solution to me. I kind of liked Max's idea of
"app('django.contrib.admin')", but maybe YAGNI on that. Let's do the
dictionary thing, assuming it's cool with Jacob as well.

jacobian

unread,
Jan 18, 2006, 4:30:09 PM1/18/06
to Django developers
At first glance, I think I prefer the "myapp.admin as admin" syntax.

It seems like the dictionary is boilerplate -- 99% of the time, you're
going to be doing::

INSTALLED_APPS = {
'news' : 'ellington.news',
'photos' : 'ellington.photos',
# etc
}

Put another way: Ellington (currently) has 71 apps, and we've not yet
run into a name conflict. I think we should optomize for the common
case and use a tuple or a list.

I'll admit there's something a little magic about adding "code" to a
string in the "foo as bar" proposal, but it strikes me as pretty
obvious magic. As it's impossible to misinterpret (in any other
situation a space in INSTALLED_APPS is an error) I think it's the most
elegant.

Jacob

Maniac

unread,
Jan 18, 2006, 5:45:30 PM1/18/06
to django-d...@googlegroups.com
Adrian Holovaty wrote:

>Looks like a good solution to me. I kind of liked Max's idea of
>"app('django.contrib.admin')", but maybe YAGNI on that. Let's do the
>dictionary thing, assuming it's cool with Jacob as well.
>
>

I hope I'm not late yet...

I kinda don't like all proposed solutions for they all make the most
common case somewhat harder. In most cases app names do not clash and
there's no need to any abstraction to the app name. And for the rare
case of clash we are obscuring a very clear syntax: a list of paths.

More than this, the current list of paths already has all the
information to distinguish apps: the path itself. In fact I think that
in most cases user's app labels would just repeat the info in path in
form of some prefixes:

INSTALLED_APPS = {
'django_admin': 'django.contrib.admin ',
'myapp_admin': 'myapp.admin'
}

See the repetition?

I propose to just let the django-admin.py accept not only last bit of
paths but also full paths. So if someone has a app name clash he will
just use:

django-admin.py install myapp.admin

I thunk this is much clearer...

hugo

unread,
Jan 18, 2006, 5:47:32 PM1/18/06
to Django developers
>I'll admit there's something a little magic about adding "code" to a
>string in the "foo as bar" proposal, but it strikes me as pretty
>obvious magic.

How about something like this:

INSTALLED_APPS = (
'foo.bar.baz',
('foo.baz.baz', 'baz2'),
)

So essentially either provide a string - in that case use the last
element - or provide a two-string-tuple - in that case use the second
element for the app name? Makes the common case as simple as it already
is, but makes the complex case simple and without weird "code as
string" stuff :-)

bye, Georg

Joseph Kocherhans

unread,
Jan 18, 2006, 5:58:08 PM1/18/06
to django-d...@googlegroups.com
On 1/18/06, Maniac <Man...@softwaremaniacs.org> wrote:
>
> I propose to just let the django-admin.py accept not only last bit of
> paths but also full paths. So if someone has a app name clash he will
> just use:
>
> django-admin.py install myapp.admin

Unfortunately, this alone doesn't solve the possible clashes between
table names or clashed between template directories. The main point of
the other proposal is to avoid extra nested directories for templates
(templates/myapp/admin vs templates/admin), and longer tablenames such
as (myapp_admin_user vs admin_user). Granted that the examples I gave
aren't *that* bad, but it's not hard to imagine a case where they
would be... What about templates/django/contrib/admin/user? I don't
think django.contrib apps should get special treatement.

I guess the least invasive option is 'myapp.admin as myadmin'.
INSTALLED_APPS for every existing django project can stay the same. I
can live with the magic there. Jacob has a point that it's pretty
obvious.

Joseph

Eugene Lazutkin

unread,
Jan 18, 2006, 8:07:13 PM1/18/06
to django-d...@googlegroups.com
hugo wrote:
>
> How about something like this:
>
> INSTALLED_APPS = (
> 'foo.bar.baz',
> ('foo.baz.baz', 'baz2'),
> )


+1.

Adrian Holovaty

unread,
Jan 18, 2006, 9:23:47 PM1/18/06
to django-d...@googlegroups.com
On 1/18/06, hugo <g...@hugo.westfalen.de> wrote:
> How about something like this:
>
> INSTALLED_APPS = (
> 'foo.bar.baz',
> ('foo.baz.baz', 'baz2'),
> )

This seems to be a good compromise -- it requires no change for the
common case, and it's not "code as string" stuff. Shall we?

Jacob Kaplan-Moss

unread,
Jan 18, 2006, 10:25:07 PM1/18/06
to django-d...@googlegroups.com
On Jan 18, 2006, at 8:23 PM, Adrian Holovaty wrote:
> On 1/18/06, hugo <g...@hugo.westfalen.de> wrote:
>> How about something like this:
>>
>> INSTALLED_APPS = (
>> 'foo.bar.baz',
>> ('foo.baz.baz', 'baz2'),
>> )
>
> This seems to be a good compromise -- it requires no change for the
> common case, and it's not "code as string" stuff. Shall we?

Sounds good to me.

Jacob

Radek Svarz

unread,
Jan 19, 2006, 12:22:23 PM1/19/06
to django-d...@googlegroups.com
What is so strange about "myapp.admin as admin" ?

Users of Django are usually familiar with such syntax - SQL uses that, Python import uses that. From the user readibility I prefer it.

With:

INSTALLED_APPS = (
    'foo.bar.baz',
    ('foo.baz.baz', 'baz2'),
)

you will have to deal with several brackets and explain what is the name and what the alias.

Radek
Reply all
Reply to author
Forward
0 new messages