* cc: nils@… (added)
* easy: => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:102>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* easy: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:103>
* easy: 1 => 0
Comment:
Not an easy picking ;)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:104>
* cc: bendavis78 (added)
* ui_ux: => 0
Comment:
Is anyone actively working on this? I'm willing to help bring the soc2010
/app-loading branch up to date with trunk, if help is needed.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:105>
* ui_ux: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:106>
Comment (by anonymous):
@bendavis78: I am pretty sure your help would be greatly appreciated -
considering the amount of attention/CC's for this ticket.
Maybe get on IRC and discuss with one or two of the core devs as to how
and whether your work might be merged into trunk as soon as possible - and
as to what the bottlenecks and design goals are for this feature. --
irc://irc.freenode.net/django
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:107>
Comment (by jezdez):
@bendavis78 Yes, arthurk and me were working on this ticket till a month
ago, see https://github.com/jezdez/django/tree/app-loading for the latest
state.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:108>
Comment (by bendavis78):
Thanks. For clarity's sake, I'm attaching a patch based on jezdez's app-
loading branch that applies cleanly against r16630 (current svn trunk). I
also have this on my github fork here:
https://github.com/savidworks/django/tree/app-loading.
Also, for the benefit of others interested in this patch, I'll do my best
to explain what it does based on what I've gleaned from the source:
----
The ```INSTALLED_APPS``` setting may now contain a reference to an
```App``` class. For example:
{{{#!python
INSTALLED_APPS = (
# ...
'django.contrib.admin',
'myapp.apps.MyApp',
)
}}}
These app classes extend ```django.apps.App```, and may define a number of
properties:
{{{#!python
from django.apps import App
class MyApp(App):
class Meta:
verbose_name = 'My sweet pony app'
}}}
Other properties that can be set on Meta are ```db_prefix``` and
```models_path```. This will allow you to override existing app
definitions in order to prevent potential conflicts.
When the app loader loops through ```INSTALLED_APPS```, it converts any
normal modules an ```App``` class and loads everything into the apps cache
(which was moved from ```django.models.loading``` to
```django.apps.cache```). This cache is, among other things, used by the
admin for introspection of apps and models.
For further customization, one may also specify how an ```App``` class is
initialized by providing kwargs in the ```INSTALLED_APPS``` setting:
{{{#!python
INSTALLED_APPS = (
# ...
('myapp.apps.MyApp', {'verbose_name':'Something else','foo':'bar'}),
)
}}}
In this case, ```MyApp``` would be initialized to the equivalent of:
{{{#!python
class MyApp(App):
foo = 'bar'
class Meta:
verbose_name = 'Something else'
}}}
----
My only question at this point is regarding the design decision to use an
options class (ie, ```MyApp.Meta```). The code suggests that other
properties may be set on your custom App class, but how might one use
custom properties on an App class? I'm sure there's a reason for not
putting verbose_name, db_prefix, and models_path in the class's main
properties, I'm just curious what the thinking is on that.
On another note, I was thinking it would also be useful to allow app
authors to define how apps should be displayed to the end user.
Specifically, I think it would be nice to be able to group and order
models in a way that would be more meaningful or helpful to admin users.
Perhaps that's one thing that could be done on within a custom App class.
Although, that might be a discussion for another time.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:109>
Comment (by jezdez):
Replying to [comment:109 bendavis78]:
> Thanks. For clarity's sake, I'm attaching a patch based on jezdez's
app-loading branch that applies cleanly against r16630 (current svn
trunk). I also have this on my github fork here:
https://github.com/savidworks/django/tree/app-loading.
Actually that wasn't really worth the hassle, you merged it wrong (left
some code from old commits in `admin/options.py`). I attached a correct
patch.
> For further customization, one may also specify how an ```App``` class
is initialized by providing kwargs in the ```INSTALLED_APPS``` setting:
> {{{#!python
> INSTALLED_APPS = (
> # ...
> ('myapp.apps.MyApp', {'verbose_name':'Something else','foo':'bar'}),
> )
> }}}
FWIW, I like the following notation better:
{{{#!python
INSTALLED_APPS = (
# ...
('myapp.apps.MyApp', {
'verbose_name': 'Something else',
'foo': 'bar',
}),
)
}}}
> My only question at this point is regarding the design decision to use
an options class (ie, ```MyApp.Meta```). The code suggests that other
properties may be set on your custom App class, but how might one use
custom properties on an App class? I'm sure there's a reason for not
putting verbose_name, db_prefix, and models_path in the class's main
properties, I'm just curious what the thinking is on that.
It's simple, `Meta` is used internally by Django during startup, so it
needs to be handled with care, reducing the chance to break a rather
fundamental part. In other words, it's internal API when it comes to app
loading and is configured depending on the (Python) meta class `AppBase`.
Using it in app-specific implementation details like looking for a
specific module in all apps (say for implementing the discovery pattern)
is fine though. If you want to override/set a specific option of an app
class we need to differ between those internal (via `_meta`) and the
"usual" class or instance attributes.
> On another note, I was thinking it would also be useful to allow app
authors to define how apps should be displayed to the end user.
Specifically, I think it would be nice to be able to group and order
models in a way that would be more meaningful or helpful to admin users.
Perhaps that's one thing that could be done on within a custom App class.
Although, that might be a discussion for another time.
That's certainly a good idea but not really part of this ticket. In other
words, this can be added at a later time on top of the new app classes.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:110>
Comment (by bendavis78):
Ah, thanks for catching my mistake in the merge.
It looks like my assumption that an App subclass can implement its own
attributes is incorrect with the current patch. Currently the python
metaclass AppBase does not propagate the class's attrs to the new_class
It only propagates ```{'__module__': module}```:
{{{#!python
def __new__(cls, name, bases, attrs):
super_new = super(AppBase, cls).__new__
parents = [b for b in bases if isinstance(b, AppBase)]
if not parents:
# If this isn't a subclass of App, don't do anything special.
return super_new(cls, name, bases, attrs)
module = attrs.pop('__module__', None)
new_class = super_new(cls, name, bases, {'__module__': module})
attr_meta = attrs.pop('Meta', None)
if not attr_meta:
meta = getattr(new_class, 'Meta', None)
else:
meta = attr_meta
app_name = attrs.pop('_name', None)
if app_name is None:
# Figure out the app_name by looking one level up.
# For 'django.contrib.sites.app', this would be
'django.contrib.sites'
app_module = sys.modules[new_class.__module__]
app_name = app_module.__name__.rsplit('.', 1)[0]
new_class.add_to_class('_meta', AppOptions(app_name, meta))
# For easier Meta inheritance
new_class.add_to_class('Meta', attr_meta)
return new_class
}}}
Thoughts? Should App subclasses not be allowed to have any attributes
other than Meta or _name?
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:111>
Comment (by jezdez):
No, you misunderstood me, the class attributes of the app classes
**shouldn't** be put into _meta since they are not part of the internal
API. This follows the same pattern as the `ModelForm` and `Model` classes
.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:112>
Comment (by jezdez):
https://github.com/jezdez/django/blob/app-
loading/django/apps/base.py#L50-55 shows pretty well how it's supped to
work:
{{{
def __init__(self, **options):
for key, value in options.iteritems():
if key in DEFAULT_NAMES:
setattr(self._meta, key, value)
else:
setattr(self, key, value)
}}}
Any parameter which is passed during initialization to the app class (e.g.
from the settings) ought to be set as an instance attribute, unless it's
one of the few internal options. It's a simple matter of easy
customization to be able to do that.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:113>
* cc: simon@… (removed)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:114>
* cc: flosch@… (removed)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:115>
Comment (by bendavis78):
Sure, I understand that they shouldn't be passed into _meta. But one
would expect any custom attributes on their app class to stay there, and
not magically disappear, correct? For example, if I create this:
{{{#!python
class MyApp(App):
foo = "bar"
}}}
the ```foo``` attribute of the class will magially disappear. This happens
because in the ''python'' metaclass, new_class is not being given the
attributes of the original class.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:116>
Comment (by jezdez):
Yeah, apologies, you're absolutely right, I've pushed a fix and attached
an updated patch.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:117>
Comment (by bendavis78):
I noticed that in the admin, app titles are not run through .title(), as
they were before the patch. It should be:
{{{#!python
app_dict[app_label] = {
'name':
apps.find_app(app_label)._meta.verbose_name.title(),
'app_url': app_label + '/',
'has_module_perms': has_module_perms,
'models': [model_dict],
}}}
(contrib/admin/sites.py, line 352)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:118>
* cc: carlos.palol@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:119>
Comment (by ramiro):
Replying to [comment:118 bendavis78]:
> I noticed that in the admin, app titles are not run through .title(), as
they were before the patch.
Actually, the application label is, in current admin code, inconsistently
run through either the `capfirst` template filter (or its underlying
function in view Python code) or tranformed by the `.title()` method.
This would be a good chance to get that fixed and IMHO allowing the app
author to define the capitalization of the label would be the best
approach (now the label can be something more complex that the app
module/package name e.g. "TLD Registries Contacts") instead of forcing
such a basic treatment like `.title()` to be always applied (same thing
for translators of that label to other languages).
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:121>
* cc: sebastian.goll@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:122>
* cc: ionel.mc@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:123>
Comment (by ramiro):
In [17389]:
{{{
#!CommitTicketReference repository="" revision="17389"
Reverted [17378] until a public API is available for application labels.
This will allow to solve the i18n of such labels in a more holistic way
without the need to introduce temporary, undocumented mechanisms to
translate them.
Refs #3591, #10436
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:124>
* cc: aav (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:125>
* cc: danols@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:126>
* cc: steffann (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:127>
* cc: pshields@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:128>
* cc: flisky (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:129>
* cc: jakub@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:130>
* cc: albrecht.andi@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:131>
* cc: JonathanBarratt (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:132>
* cc: marc.tamlyn@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:133>
Comment (by akaariai):
2b9fb2e6443c04e4415b17083d727bd80047b6e5 fixed a deadlock in app loading.
It does not contain tests as it seemed too hard to write one into Django's
test suite. So, a heads up: the app-loading refactor should take care not
to reintroduce the deadlock condition again. Refs #18251.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:134>
* cc: flavio.curella@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:135>
Comment (by paramburu):
Wanted to let you know I've started a discussion on the django developers
group that is related to this ticket. I would appreciate your opinions
regarding the topic and advice on how to make it go forward.
[https://groups.google.com/forum/?fromgroups=#!topic/django-
developers/7f0gKen2ces]
Thank you in advance for the troubles.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:136>
* cc: 4glitch@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:137>
* stage: Fixed on a branch => Accepted
Comment:
The GSoC branch is out of date.
The latest efforts are in the [https://github.com/ptone/django/tree/app-
loading app-loading branch].
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:138>
* cc: luc.saffre@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:139>
* cc: zachborboa+django@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:140>
Comment (by malavon_despana@…):
My suggestion: Let the developer declare in the application package's
__init__.py something like:
class Meta: #or whatever the name should be.
verbose_name = _(u"App title for stuff like Admin")
... perhaps more stuff would be convenient here ...
Keepin' seein' the raw name in the admin interface just sucks :(.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:142>
* cc: vlastimil@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:143>
* cc: django@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:144>
* cc: akanouras (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:145>
* cc: unpig (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:146>
* cc: ua_django_bugzilla@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:147>
Comment (by russellm):
#21018 raised an interesting point about ordering in INSTALLED_APPS that
should be tracked as part of this issue.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:148>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:149>
* cc: someuniquename@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:150>
* cc: bendavis78 (removed)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:151>
* cc: danielsamuels (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:152>
* ui_ux: 1 => 0
Comment:
WIP https://github.com/django/django/pull/2076
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:153>
* needs_better_patch: 1 => 0
Comment:
Thread https://groups.google.com/d/msg/django-
developers/_iggZzrYtJQ/FWFPgCflSnkJ
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:154>
* has_patch: 1 => 0
Comment:
Django now supports a custom verbose_name (in master, which will become
1.7).
There's no patch available for the next steps.
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:155>
* status: new => closed
* resolution: => fixed
Comment:
This ticket has become long and unwieldy.
Since the hardest part of the refactoring is done, I'm going to close it.
One of the two original features is implemented and the other is tracked
in #21683.
I'm filing a series of smaller tickets for remaining or related tasks:
https://code.djangoproject.com/query?status=!closed&keywords=~app-loading
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:156>
* keywords: => app-loading
--
Ticket URL: <https://code.djangoproject.com/ticket/3591#comment:157>