http://www.aaronsw.com/weblog/rewritingreddit
The magic-removal branch addresses the ORM issues he raised. A
remaining problem is the disorientating namespace.
View modules typically begin with ugly boilerplate like:
---
from django.core.extensions import DjangoContext as Context
from django.core.extensions import render_to_response,
get_object_or_404
from django.core.exceptions import Http404
from django.utils.httpwrappers import HttpResponse,
HttpResponseRedirect
from django.core.template.loader import render_to_string
...
---
As Aaron says, it is not obvious to the outsider what the underlying
structure of the package hierarchy is. I suspect this is a common
problem in projects that have evolved to meet the needs of a busy
production environment.
The most confusing aspect is the second level of the namespace. What
is core? What are utils? And what counts as an extension?
What about something like this:
django.utils.httpwrappers -> django.http
django.core.template -> django.template
- includes Context/DjangoContext
django.core.exceptions -> django.error
django.core.extensions -> django.shortcuts
- includes render_to_string
django.contrib -> django.apps
django.utils.feedgenerator -> django.feed
django.core.formfields -> django.form
If the names are kept short and predictable then it becomes feasible
to import and use the second tier directly, which could simplify the
basic boilerplate down to:
---
from django import http, template, error
from django.shortcuts import *
def basic_view(request):
t = template.get('mytemplate') # get <- get_template
c = template.Context({'name':'yehudi'})
return http.Response(t.render(c)) # Response <- HttpResponse
def shortcut_view(request):
return render_to_response('mytemplate', {'name':'yehudi'})
---
This might not be a backwards-compatibility nightmare because the
existing namespace could be preserved by importing from the new
namespace. For example, if django.core.exceptions goes to
django.error then django.core.exceptions becomes:
---
from django.error import *
---
Thoughts?
Kieran
Yeah, this is a very good point.
I'm slightly against the namespace churn you suggest (e.g.
"django.core.exceptions" -> "django.errors") simply because one man's
"intuitive" is another's "confusing." No matter how we rename stuff,
with a package as big as Django someone is always going to think we
named it wrong.
One altertative to your proposal that Adrian and I tossed around at
one point was to alias certain "normal" modules into a set of
"tasks." That way writing a view would become::
from django.tasks.views import *
def view(request):
return render_to_response(....)
And writing a template tag::
from django.tasks.templatetags import *
Etc.
Hm?
Jacob
+1 from me - that would allow to provide "simplified" namespaces by
still keeping the basic structure in place (as the tasks could just be
importing modules without their own code). Especially this would give a
good way to have only high level interfaces in those tasks and keeping
low-level stuff for advanced usage in their original places - and
therefore would be a good starting point for a API documentation in two
(or more) layers (having a simplified-but-powerful base API and an
advanced-usage API could make some stuff much easier to learn).
bye, Georg
+1. I think this is the way to go.
This would certainly be a vast improvement from an end-user's
perspective and it would mean that the screencasts wouldn't have to
skip over that bit ;)
Actually I think there are at least two separate problems here:
1) Too much boilerplate (end-user problem)
2) Too hard to navigate Django code base (advanced user and new
developer problem)
I agree that there is no One True Way to structure a package so that
it seems intuitive to everyone. The namespace churn I put forward was
really just to stimulate discussion about how the current structure
might be improved. As I said, I think that the main problem is the
second tier, which does little to clarify purpose. (extract from
subconscious mind: "httpwrappers"...that sounds pretty
"core"..."mail"...i know this one - that's definitely a utility...)
Those who have commented so far are all pretty intimate with the
existing code base so for you lot problem 2 may not exist. The
benefits would be mostly to new and dementing folk. Django has the
luxury of having control over the namespace of the entire component
set, but this cannot yet be considered a feature.
+1 on the tasks idea being a quick fix for problem 1 - though this
creates a new problem: What are the basic requirements for any view?
Do you have a list in mind?
Kieran
+1. I'm a big fan of this. django.http would get that'd get the
current contents of django.utils.httpwrappers, plus the Http404 and
Http500 exceptions.
> django.core.template -> django.template
> - includes Context/DjangoContext
+1. Another great change.
> django.core.exceptions -> django.error
+0. I'm not as excited about this one; could go either way.
> django.core.extensions -> django.shortcuts
> - includes render_to_string
+1. "django.shortcuts" is a *perfect* name for this module.
> django.contrib -> django.apps
-1 on this. "contrib" is a well-established name for "extra stuff" --
and the code in contrib isn't necessarily all Django applications. For
example, django.contrib.markup is just a bunch of template tags.
> django.utils.feedgenerator -> django.feed
-0 on this, only because the feedgenerator isn't used that often.
> django.core.formfields -> django.form
+1. Nice and short.
Let's get some more feedback quickly and move forward with this. Also,
is anybody interested in implementing this code in magic-removal?
Kieran?
Adrian
--
Adrian Holovaty
holovaty.com | djangoproject.com | chicagocrime.org
On 1/7/06, kmh <kieran....@gmail.com> wrote:
> django.core.exceptions    -> django.error
I like this idea, but I think that shortcuts of whatever should use
explicit imports such as
from django.core.extensions import DjangoContext, render_to_response, etc....
rather than
from django.core.extensions import *
This makes it a lot easier to tell what exactly you'll get if you
import django.shortcuts. I've worked with a bunch of projects that had
something like myproject.api that had a bunch of from X import *. It's
a lot more convenient to be able to read the code than to have to use
dir(module) or track down what's in all those modules.
> Let's get some more feedback quickly and move forward with this. Also,
> is anybody interested in implementing this code in magic-removal?
> Kieran?
I'm willing to help if needed.
Joseph
Yes, most definitely. The "simplified API importer" should only do
explicit imports of the stuff that should go in there, so that their
namespace is really simple and doesn't contain any surprises. In a
best-case scenario, they would _only_ include the names that are
documented in the "simplified API". And we should try to reach that
best-case scenario, if we really want to stick to the tagline "the web
framework for _perfectionists_ with deadlines" ;-)
bye, Georg
Your opinion of the my suggestions fits pretty closely with mine.
Adrian Holovaty wrote:
> On 1/7/06, kmh <kieran....@gmail.com> wrote:
> > django.utils.httpwrappers -> django.http
>
> +1. I'm a big fan of this. django.http would get that'd get the
> current contents of django.utils.httpwrappers, plus the Http404 and
> Http500 exceptions.
If you moved the Http exceptions in here then I could easily forget the
change to the exceptions module.
> > django.contrib -> django.apps
>
> -1 on this. "contrib" is a well-established name for "extra stuff" --
> and the code in contrib isn't necessarily all Django applications. For
> example, django.contrib.markup is just a bunch of template tags.
This one was not a biggy. But in my opinion even markup is an
application, in the Django sense, and to me "apps" is snappier than
"contrib". Anything incorporated into Django proper is more than just
a "contribution" too - it is a Django stamped and approved feature. I
would like to see a "contributions" page on www.djangoproject.com
though.
> > django.utils.feedgenerator -> django.feed
>
> -0 on this, only because the feedgenerator isn't used that often.
This was with a view to the future, as this module is going to become
more and more important.
> Let's get some more feedback quickly and move forward with this. Also,
> is anybody interested in implementing this code in magic-removal?
> Kieran?
I'd love to help but I would rather not commit to this because I am
not working with the magic-removal branch and I know that there is
pressure to get this branch out the door - I can't guarantee the time
will be there at the moment.
Kieran
If the aim is to have a single import for simple views like:
from django.tasks.views import *
then that module should definitely do explicit imports from other
modules
so that it is easy to follow where things are coming from.
My idea with django.shortcuts was to contain the functions that wrap up
a bunch of Django functionality into a one-liner (render_to_response,
render_to_string, get_object_or_404).
Kieran
>From a user (and ease-of-entry) standpoint the simplest possible
syntax would be
from django import *
I don't know about most of you, but I'm already importing pretty much
all of Django anyway, so I'm not sure this is as expensive as it
sounds. With this approach, you don't have to CARE about how the
subprojects are organized until you are a much more experienced user
(or have labelled yourself a developer :-), which IMHO is as it should
be.
A vehement "no" to this. I strongly, strongly dislike the ambiguity of
"import *" statements. Plus, there's a *ton* of stuff in Django, and
importing *all* of it is extremely messy.
I've added a new page to the wiki [1] (and a link to that page [2])
describing what decisions were made (mostly based on what Adrian said)
Please check it out and modify it as necessary (I may have
misinterpreted something). I can't commit to doing the whole thing
right now, but I think maybe we could just stick our name next to a
change on that wiki page to claim it. I'll can on them as I get time,
but I won't hold anyone else back. Will that work for everyone?
Joseph
[1] http://code.djangoproject.com/wiki/NamespaceSimplification
[2] http://code.djangoproject.com/wiki/RemovingTheMagic
You're right. 'forms' fits better with the top level packages than
'form' anyhow. I'll change the wiki.
Joseph
Hmm... what about django.template (singular) becoming django.templates
(plural)? Any strong preferences? I think templates makes more sense.
Joseph
django.templates suggests a collection of templates. django.template
suggests a library, imo.
Plurals are good: forms + templates
One thing that nobody has yet expressed an opinion about was the
suggestion to provide new module attribute names to facilitate
readability when importing the second level packages (which I would
suggest becomes the recommended usage):
---
from django import http, templates
def basic_view(request):
# templates gains functions currently in template.loader ? rename
t = templates.get('mytemplate')
c = templates.Context({'name':'yehudi'})
# http classes lose Http prefix
return http.Response(t.render(c))
---
Other candidates for renaming in template.loader would be
select_template -> select, get_template_from_string -> from_string,
find_template_source -> find_source
One issue is that if Http404 goes into http we can't have http.404.
I have seen other frameworks use http.FourOhFour but I prefer
http.NotFound
Kieran
I've got a patch ready to commit that moves django.utils.httpwrappers
to django.http and updates all the dependencies and docs. I'd move
Http404 in another commit. Also, if we are going to rename the classes
in here, (as suggested by Kieran in the last email) I'd do that in a
sepatate commit as well. No one has commented on that though.
I can't think of any reason to do django/http/__init__.py vs
django/http.py other than the former looks more like everything else
in django/. Adrian or Jacob, what's your preference, and should I go
ahead and commit it?
Joseph
Let's hold off on renaming the classes for now (which ones, anyway --
the exceptions?).
> I can't think of any reason to do django/http/__init__.py vs
> django/http.py other than the former looks more like everything else
> in django/. Adrian or Jacob, what's your preference, and should I go
> ahead and commit it?
Let's go with the http package, with an __init__.py in it, simply
because it makes it more flexible to put stuff in there in the future.
I'm excited to see the change!
> Let's go with the http package, with an __init__.py in it, simply
> because it makes it more flexible to put stuff in there in the future.
This raises an issue of coding style: my feeling, though PEP 8 (the
python style guide) doesn't rule on it, is that __init__.py is
intended primarily for manipulating the package namespace. Currently
template/__init__.py and meta/__init__.py (soon to be joined by
http/__init__.py) are loaded with code.
I wonder whether people would think it worthwhile to extract this code
out into modules, importing just the names that we want accessible at
a package level back into __init__.py? It's largely an issue of
taste, but it would make it clear what you're getting when you import
the package.
Not urgent but worth ruling on at some stage.
Kieran
It's finished. If we can get the other issues settled (mostly just
naming decisions, form or forms, template or templates) I can probably
get these all done (except shortcuts) before next monday.
Joseph
One thing, with all of changes, the django.db.models thing ends up being
quite deep for such a core part. Thoughts?
The current docs reflect the 0.91 release, which I think is where the
emphasis should lie.
Next to that we should have a copy of the 0.91 in a development
location for people tracking the development version.
djangoproject.com/documentation/dev/
djangoproject.com/documentation/svn/
are two that pop to my mind, dev is more version control agnostic. Opinions?
--
Jeroen Ruigrok van der Werven
We've done some of the changes to the docs, but not all. If you're
interested in helping, great! Patches are always, always welcome. :)
Here's how we're doing it currently:
* Docs for 0.90 were frozen when 0.91 was released. They're available
at http://www.djangoproject.com/documentation/0_90/ .
* The "standard" docs are for 0.91 *and* the development (SVN)
version, and they're here: http://www.djangoproject.com/documentation/
. Any feature that's changed in the development version is marked with
"**New in Django development version.**"
The reasoning behind using the same docs for the latest release (0.91)
and SVN is that we make a *lot* of documentation improvements, and
users of 0.91 should benefit from those -- i.e., the docs for 0.91
shouldn't be frozen.
Fair enough Adrian. I understand what you mean, it leverages the
comments more that way. Just make sure you really use a NOTE in big
bold neon letters. ;)
--
Well no one seems to have much argument on either side of the form vs
forms and template vs templates sides, it's all really just personal
preference anyhow, so would Adrian or Jacob mind just issuing a
proclamation on this? ;-) I can get both of these changes done in the
next couple of days barring any emergencies.
Joseph
I think django.models sounds nice, although it would be confusing for
existing users (aside from the 5-ish people who are familiar with
magic-removal)
Joseph
Let's keep it as django.db.models -- there's no telling whether we'll
include another type of data-access layer in the future, such as an
RDF backend, which would be equally deserving of the name "models".
Let's go ahead with this one: django.core.template becomes django.template.
While we're at it, let's rename DjangoContext to something that
reflects the fact that you pass in an HttpRequest object and it has
context processors. RequestContext, SuperContext, FlexContext,
AdvancedContext -- those ideas are all pretty lame. Ideas?
> > > django.core.formfields -> django.form
django.core.formfields --> django.forms, to maintain the plural. (Yes,
django.template isn't plural, but it doesn't seem right to call it
"templates".)
Good idea to rename DjangoContext. My favorite alternative:
DjangoContext --> Context
Context --> PlainContext or SimpleContext
As for django.forms - I think that consistency in naming is more
important than the actual names so if it's to be django.template then
I'd much prefer django.form (just in case our benevolent dictator sees
fit to change his mind ;)
Kieran
> While we're at it, let's rename DjangoContext to something that
> reflects the fact that you pass in an HttpRequest object and it has
> context processors. RequestContext, SuperContext, FlexContext,
> AdvancedContext -- those ideas are all pretty lame. Ideas?
It doesn't lend itself to succinct naming :) I'll throw
DelegatedContext, ProcessingContext, IncreasedContext,
AccessoryContext, AuxContext (for Auxiliary, but that'd be a pain to
write), AugmentedContext, PseudoContext and ProxyContext into the mix.
Lastly, HttpRequestProcessingContext which I think is very
descriptive. Which is good right? :]
- Daniel
+1
I prefer SimpleContext over PlainContext.
Joseph
I like this a lot! SimpleContext is good...Other thoughts?
Now I like EmptyContext
Kieran
>I like this a lot! SimpleContext is good...Other thoughts?
>
>
I'd say BaseContext. It's now just a base class for other actually
useful contexts.
Hm, I actually liked RequestContext and Context :
Context : provides the functionality of a context, is empty to start
with, and is the context you will get in a place where you are
"insulated" from the request (eg in an inclusion tag, the context
created for the included template is a Context ).
RequestContext : A context that has been populated using information
from the request.
"Simple" implies to me that it is "for the same purpose" as other things
called *Context, but has an easier to understand/trivial implementation.
This isn't really true - its for a different thing.
Also, calling the request-filled context Context would seem to imply
that it is ok to rely on it in the implementation of the template system.
Anything is better than DjangoContext though.
+1
> "Simple" implies to me that it is "for the same purpose" as other things
> called *Context, but has an easier to understand/trivial implementation.
> This isn't really true - its for a different thing.
SimpleContext is also not quite descriptive in my opinion.
With Context as a base class and RequestContext you know what you are
superclassing. At least in my view.
Anything's better than DjangoContext. Except maybe DjangoFrameworkContext.
Let's go with Context and RequestContext. Onward!
BaseContext?