From 2d49f70b0d2fb566ffbc3d7bc78b057c6f84b13f Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 00:25:48 +0000 Subject: [PATCH 01/10] Small style cleanup of docs/generic_views.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1256 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/generic_views.txt | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/generic_views.txt b/docs/generic_views.txt index 9db1577d71..16a3c2d5bc 100644 --- a/docs/generic_views.txt +++ b/docs/generic_views.txt @@ -76,33 +76,34 @@ couple of common cases: rendering a template when no view logic is needed, and issuing a redirect. These views are: ``direct_to_template`` - Renders a given template using any extra parameters passed in the - urlpattern; requires the ``template`` argument. - + Renders a given template, passing it a ``{{ params }}`` template variable, + which is a dictionary of the parameters captured in the URL. This requires + the ``template`` argument. + For example, given the following URL patterns:: - + urlpatterns = patterns('django.views.generic.simple', - (r'^foo/$', 'direct_to_template', {'template' : 'foo_index'}), - (r'^foo/(?P\d+)/$', 'direct_to_template', {'template' : 'foo_detail'}), + (r'^foo/$', 'direct_to_template', {'template': 'foo_index'}), + (r'^foo/(?P\d+)/$', 'direct_to_template', {'template': 'foo_detail'}), ) - + ... a request to ``/foo/`` would cause the ``foo_index`` template to be rendered, and a request to ``/foo/15/`` would cause the ``foo_detail`` template to be rendered with a context variable ``{{ params.id }}`` that is set to ``15``. - + ``redirect_to`` Issue a redirect to a given URL. - The given url may contain dict-style string formatting which will be + The given URL may contain dict-style string formatting, which will be interpolated against the params in the URL. For example, to redirect from ``/foo//`` to ``/bar//``, you could use the following urlpattern:: urlpatterns = patterns('django.views.generic.simple', ('^foo/(?p\d+)/$', 'redirect_to', {'url' : '/bar/%(id)s/'}), ) - - If the given url is ``None``, a HttpResponseGone (410) will be issued. + + If the given URL is ``None``, an ``HttpResponseGone`` (410) will be issued. Using date-based generic views ============================== From a469d821a12fc337d534cb9d499942296c1bd126 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 00:33:50 +0000 Subject: [PATCH 02/10] Changed FormWrapper.fields (from [1253]) to be a property, so that it's only called when needed. git-svn-id: http://code.djangoproject.com/svn/django/trunk@1257 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/formfields.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/django/core/formfields.py b/django/core/formfields.py index e31867ce6e..dc016684f0 100644 --- a/django/core/formfields.py +++ b/django/core/formfields.py @@ -108,7 +108,6 @@ class FormWrapper: def __init__(self, manipulator, data, error_dict): self.manipulator, self.data = manipulator, data self.error_dict = error_dict - self.fields = [self.__getitem__(field.field_name) for field in self.manipulator.fields] def __repr__(self): return repr(self.data) @@ -128,6 +127,15 @@ class FormWrapper: def has_errors(self): return self.error_dict != {} + def _get_fields(self): + try: + return self._fields + except AttributeError: + self._fields = [self.__getitem__(field.field_name) for field in self.manipulator.fields] + return self._fields + + fields = property(_get_fields) + class FormFieldWrapper: "A bridge between the template system and an individual form field. Used by FormWrapper." def __init__(self, formfield, data, error_list): From 464e84257d1e61468bc6ddd3cc5ed0343ec6b047 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 02:00:23 +0000 Subject: [PATCH 03/10] Changed 'django-admin.py startapp' application template to use views.py instead of views package, for simplicity. Updated tutorial to reflect the change. git-svn-id: http://code.djangoproject.com/svn/django/trunk@1258 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/conf/app_template/views.py | 1 + django/conf/app_template/views/__init__.py | 0 docs/tutorial01.txt | 3 +- docs/tutorial03.txt | 47 ++++++++++++---------- docs/tutorial04.txt | 10 ++--- 5 files changed, 33 insertions(+), 28 deletions(-) create mode 100644 django/conf/app_template/views.py delete mode 100644 django/conf/app_template/views/__init__.py diff --git a/django/conf/app_template/views.py b/django/conf/app_template/views.py new file mode 100644 index 0000000000..60f00ef0ef --- /dev/null +++ b/django/conf/app_template/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/django/conf/app_template/views/__init__.py b/django/conf/app_template/views/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt index 761b73466d..edf59b5b54 100644 --- a/docs/tutorial01.txt +++ b/docs/tutorial01.txt @@ -131,8 +131,7 @@ That'll create a directory structure like this:: models/ __init__.py polls.py - views/ - __init__.py + views.py This directory structure will house the poll application. diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt index 8d0566ffcf..ebf1515aa3 100644 --- a/docs/tutorial03.txt +++ b/docs/tutorial03.txt @@ -73,10 +73,10 @@ this:: from django.conf.urls.defaults import * urlpatterns = patterns('', - (r'^polls/$', 'myproject.apps.polls.views.polls.index'), - (r'^polls/(?P\d+)/$', 'myproject.apps.polls.views.polls.detail'), - (r'^polls/(?P\d+)/results/$', 'myproject.apps.polls.views.polls.results'), - (r'^polls/(?P\d+)/vote/$', 'myproject.apps.polls.views.polls.vote'), + (r'^polls/$', 'myproject.apps.polls.views.index'), + (r'^polls/(?P\d+)/$', 'myproject.apps.polls.views.detail'), + (r'^polls/(?P\d+)/results/$', 'myproject.apps.polls.views.results'), + (r'^polls/(?P\d+)/vote/$', 'myproject.apps.polls.views.vote'), ) This is worth a review. When somebody requests a page from your Web site -- @@ -84,8 +84,8 @@ say, "/polls/23/", Django will load this Python module, because it's pointed to by the ``ROOT_URLCONF`` setting. It finds the variable named ``urlpatterns`` and traverses the regular expressions in order. When it finds a regular expression that matches -- ``r'^polls/(?P\d+)/$'`` -- it loads the -associated Python package/module: ``myproject.apps.polls.views.polls.detail``. That -corresponds to the function ``detail()`` in ``myproject/apps/polls/views/polls.py``. +associated Python package/module: ``myproject.apps.polls.views.detail``. That +corresponds to the function ``detail()`` in ``myproject/apps/polls/views.py``. Finally, it calls that ``detail()`` function like so:: detail(request=, poll_id=23) @@ -99,9 +99,9 @@ what you can do with them. And there's no need to add URL cruft such as ``.php`` -- unless you have a sick sense of humor, in which case you can do something like this:: - (r'^polls/latest\.php$', 'myproject.apps.polls.views.polls.index'), + (r'^polls/latest\.php$', 'myproject.apps.polls.views.index'), -But, don't do that. It's stupid. +But, don't do that. It's silly. If you need help with regular expressions, see `Wikipedia's entry`_ and the `Python documentation`_. Also, the O'Reilly book "Mastering Regular @@ -125,16 +125,21 @@ Fire up the Django development Web server:: django-admin.py runserver --settings=myproject.settings Now go to "http://localhost:8000/polls/" on your domain in your Web browser. -You should get a Python traceback with the following error message:: +You should get a pleasantly-colored error page with the following message:: - ViewDoesNotExist: Could not import myproject.apps.polls.views.polls. Error - was: No module named polls + ViewDoesNotExist at /polls/ + + Tried index in module myproject.apps.polls.views. Error was: 'module' + object has no attribute 'index' + +This error happened because you haven't written a function ``index()`` in the +module ``myproject/apps/polls/views.py``. Try "/polls/23/", "/polls/23/results/" and "/polls/23/vote/". The error -messages should tell you which view Django tried (and failed to find, because -you haven't written any views yet). +messages tell you which view Django tried (and failed to find, because you +haven't written any views yet). -Time to write the first view. Create the file ``myproject/apps/polls/views/polls.py`` +Time to write the first view. Open the file ``myproject/apps/polls/views.py`` and put the following Python code in it:: from django.utils.httpwrappers import HttpResponse @@ -374,19 +379,19 @@ Take some time to play around with the views and template system. As you edit the URLconf, you may notice there's a fair bit of redundancy in it:: urlpatterns = patterns('', - (r'^polls/$', 'myproject.apps.polls.views.polls.index'), - (r'^polls/(?P\d+)/$', 'myproject.apps.polls.views.polls.detail'), - (r'^polls/(?P\d+)/results/$', 'myproject.apps.polls.views.polls.results'), - (r'^polls/(?P\d+)/vote/$', 'myproject.apps.polls.views.polls.vote'), + (r'^polls/$', 'myproject.apps.polls.views.index'), + (r'^polls/(?P\d+)/$', 'myproject.apps.polls.views.detail'), + (r'^polls/(?P\d+)/results/$', 'myproject.apps.polls.views.results'), + (r'^polls/(?P\d+)/vote/$', 'myproject.apps.polls.views.vote'), ) -Namely, ``myproject.apps.polls.views.polls`` is in every callback. +Namely, ``myproject.apps.polls.views`` is in every callback. Because this is a common case, the URLconf framework provides a shortcut for common prefixes. You can factor out the common prefixes and add them as the first argument to ``patterns()``, like so:: - urlpatterns = patterns('myproject.apps.polls.views.polls', + urlpatterns = patterns('myproject.apps.polls.views', (r'^polls/$', 'index'), (r'^polls/(?P\d+)/$', 'detail'), (r'^polls/(?P\d+)/results/$', 'results'), @@ -435,7 +440,7 @@ Now that we've decoupled that, we need to decouple the 'myproject.apps.polls.urls' urlconf by removing the leading "polls/" from each line:: - urlpatterns = patterns('myproject.apps.polls.views.polls', + urlpatterns = patterns('myproject.apps.polls.views', (r'^$', 'index'), (r'^(?P\d+)/$', 'detail'), (r'^(?P\d+)/results/$', 'results'), diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt index 4f9ef3baff..7acb1343eb 100644 --- a/docs/tutorial04.txt +++ b/docs/tutorial04.txt @@ -44,9 +44,9 @@ Now, let's create a Django view that handles the submitted data and does something with it. Remember, in `Tutorial 3`_, we create a URLconf that included this line:: - (r'^polls/(?P\d+)/vote/$', 'myproject.apps.polls.views.polls.vote'), + (r'^polls/(?P\d+)/vote/$', 'myproject.apps.polls.views.vote'), -So let's create a ``vote()`` function in ``myproject/apps/polls/views/polls.py``:: +So let's create a ``vote()`` function in ``myproject/apps/polls/views.py``:: from django.core.extensions import get_object_or_404, render_to_response from django.models.polls import choices, polls @@ -158,7 +158,7 @@ so far:: from django.conf.urls.defaults import * - urlpatterns = patterns('myproject.apps.polls.views.polls', + urlpatterns = patterns('myproject.apps.polls.views', (r'^$', 'index'), (r'^(?P\d+)/$', 'detail'), (r'^(?P\d+)/results/$', 'results'), @@ -178,7 +178,7 @@ Change it like so:: (r'^$', 'django.views.generic.list_detail.object_list', info_dict), (r'^(?P\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict), (r'^(?P\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results')), - (r'^(?P\d+)/vote/$', 'myproject.apps.polls.views.polls.vote'), + (r'^(?P\d+)/vote/$', 'myproject.apps.polls.views.vote'), ) We're using two generic views here: ``object_list`` and ``object_detail``. @@ -217,7 +217,7 @@ In the ``vote()`` view, change the template call from ``polls/detail`` to ``polls/polls_detail``, and pass ``object`` in the context instead of ``poll``. Finally, you can delete the ``index()``, ``detail()`` and ``results()`` views -from ``polls/views/polls.py``. We don't need them anymore. +from ``polls/views.py``. We don't need them anymore. For full details on generic views, see the `generic views documentation`_. From 3301999387d3c004cdf30fefb434e84f12fba2d2 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 02:57:03 +0000 Subject: [PATCH 04/10] Upgraded ez_setup.py from 0.6a5 to 0.6a7 git-svn-id: http://code.djangoproject.com/svn/django/trunk@1259 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- ez_setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ez_setup.py b/ez_setup.py index 248f4078a4..b9d4f2dae0 100644 --- a/ez_setup.py +++ b/ez_setup.py @@ -14,7 +14,7 @@ the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import sys -DEFAULT_VERSION = "0.6a5" +DEFAULT_VERSION = "0.6a7" DEFAULT_URL = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3] md5_data = { @@ -30,6 +30,10 @@ md5_data = { 'setuptools-0.6a4-py2.4.egg': '7f33c3ac2ef1296f0ab4fac1de4767d8', 'setuptools-0.6a5-py2.3.egg': '748408389c49bcd2d84f6ae0b01695b1', 'setuptools-0.6a5-py2.4.egg': '999bacde623f4284bfb3ea77941d2627', + 'setuptools-0.6a6-py2.3.egg': '7858139f06ed0600b0d9383f36aca24c', + 'setuptools-0.6a6-py2.4.egg': 'c10d20d29acebce0dc76219dc578d058', + 'setuptools-0.6a7-py2.3.egg': 'cfc4125ddb95c07f9500adc5d6abef6f', + 'setuptools-0.6a7-py2.4.egg': 'c6d62dab4461f71aed943caea89e6f20', } import sys, os From b2424a391a42a01b32b5fd9a337f93092d842ac8 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 02:57:38 +0000 Subject: [PATCH 05/10] Updated setup.py to include locales and *.TXT in package_data. Changed version to 0.90. git-svn-id: http://code.djangoproject.com/svn/django/trunk@1260 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- setup.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index def9ad1360..4183faab39 100644 --- a/setup.py +++ b/setup.py @@ -4,8 +4,8 @@ ez_setup.use_setuptools() from setuptools import setup, find_packages setup( - name = "django", - version = "1.0.0", + name = "Django", + version = "0.90", url = 'http://www.djangoproject.com/', author = 'Lawrence Journal-World', author_email = 'holovaty@gmail.com', @@ -13,6 +13,26 @@ setup( license = 'BSD', packages = find_packages(), package_data = { + '': ['*.TXT'], + 'django.conf': ['locale/bn/LC_MESSAGES/*', + 'locale/cs/LC_MESSAGES/*', + 'locale/cy/LC_MESSAGES/*', + 'locale/da/LC_MESSAGES/*', + 'locale/de/LC_MESSAGES/*', + 'locale/en/LC_MESSAGES/*', + 'locale/es/LC_MESSAGES/*', + 'locale/fr/LC_MESSAGES/*', + 'locale/gl/LC_MESSAGES/*', + 'locale/is/LC_MESSAGES/*', + 'locale/it/LC_MESSAGES/*', + 'locale/no/LC_MESSAGES/*', + 'locale/pt_BR/LC_MESSAGES/*', + 'locale/ro/LC_MESSAGES/*', + 'locale/ru/LC_MESSAGES/*', + 'locale/sk/LC_MESSAGES/*', + 'locale/sr/LC_MESSAGES/*', + 'locale/sv/LC_MESSAGES/*', + 'locale/zh_CN/LC_MESSAGES/*'], 'django.contrib.admin': ['templates/admin/*.html', 'templates/admin_doc/*.html', 'templates/registration/*.html', 'media/css/*.css', 'media/img/admin/*.gif', From 93519513a14e1c4990786bd0c5d6eb8e18e75d09 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 02:59:22 +0000 Subject: [PATCH 06/10] Added links to auth docs in docs/templates_python.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1261 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/templates_python.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/templates_python.txt b/docs/templates_python.txt index 81c423f33b..48c17c63ae 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -246,11 +246,12 @@ variables: * ``user`` -- An ``auth.User`` instance representing the currently logged-in user (or an ``AnonymousUser`` instance, if the client isn't - logged in). + logged in). See the `user authentication docs`. * ``messages`` -- A list of ``auth.Message`` objects for the currently logged-in user. * ``perms`` -- An instance of ``django.core.extensions.PermWrapper``, - representing the permissions that the currently logged-in user has. + representing the permissions that the currently logged-in user has. See + the `permissions docs`_. Also, if your ``DEBUG`` setting is set to ``True``, every ``DjangoContext`` instance has the following two extra variables: @@ -280,6 +281,9 @@ This technique has two caveats: * You'll have to be careful not to set the variable ``current_time`` when you populate this context. If you do, you'll override the other one. +.. _user authentication docs: http://www.djangoproject.com/documentation/models/authentication/#users +.. _permissions docs: http://www.djangoproject.com/documentation/models/authentication/#permissions + Loading templates ----------------- From 6b870c136bc87cb7b284301ee9eb0560cf16f66d Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 03:09:50 +0000 Subject: [PATCH 07/10] Changed tutorial02 not to say redirects and flatpages are included git-svn-id: http://code.djangoproject.com/svn/django/trunk@1262 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/tutorial02.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorial02.txt b/docs/tutorial02.txt index e79c067ad5..5dc326b1d4 100644 --- a/docs/tutorial02.txt +++ b/docs/tutorial02.txt @@ -81,8 +81,8 @@ Now, try logging in. You should see the Django admin index page: :alt: Django admin index page :target: http://media.djangoproject.com/img/doc/tutorial/admin02.png -By default, you should see four types of editable content: groups, users, -redirects and flat pages. These are core features Django ships with by default. +By default, you should see two types of editable content: groups and users. +These are core features Django ships with by default. .. _"I can't log in" questions: http://www.djangoproject.com/documentation/faq/#the-admin-site From 17d54d1d9ef6d0f07b5527f54761785988d5fcf9 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 03:37:01 +0000 Subject: [PATCH 08/10] Fixed #808 -- Fixed typo in docs/forms.txt. Thanks, limodou git-svn-id: http://code.djangoproject.com/svn/django/trunk@1263 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/forms.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/forms.txt b/docs/forms.txt index 969ebd428d..8d2f2ead9c 100644 --- a/docs/forms.txt +++ b/docs/forms.txt @@ -389,7 +389,7 @@ You use this custom manipulator exactly as you would use an auto-generated one. Here's a simple function that might drive the above form:: def contact_form(request): - manipulator = ContactFormManipulator() + manipulator = ContactManipulator() if request.POST: new_data = request.POST.copy() errors = manipulator.get_validation_errors(new_data) From 674c0b353ceaace921eb3d1b5b0293b35a41ad2e Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 16 Nov 2005 05:35:59 +0000 Subject: [PATCH 09/10] Added official-version information to docs/install.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@1265 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/install.txt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/install.txt b/docs/install.txt index 82d51a667c..c961411f8e 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -77,12 +77,19 @@ It's easy either way. Installing the official version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There IS no official version yet. But once there is, here's how it'll work: +1. Download Django-0.90.tar.gz from our `download page`_. +2. ``tar xzvf Django-0.90.tar.gz`` +3. ``cd Django-0.90`` +4. ``sudo python setup.py install`` -1. Download the tarball of the latest official version from our `download page`_. -2. ``tar xzvf django-1.0.0.tar.gz`` -3. ``cd django-1.0.0`` -4. ``python setup.py install`` +Note that the last command will automatically download and install setuptools_ +if you don't already have it installed. This requires a working Internet +connection. + +This will install Django in your Python installation's ``site-packages`` +directory. + +.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools Installing the development version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From eda3e2c99a80a94e4bfbb30f13c931523a63746f Mon Sep 17 00:00:00 2001 From: Georg Bauer Date: Wed, 16 Nov 2005 12:13:28 +0000 Subject: [PATCH 10/10] fixed a bug that happened only if the very first gettext call was an ngettext git-svn-id: http://code.djangoproject.com/svn/django/trunk@1266 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/utils/translation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django/utils/translation.py b/django/utils/translation.py index 90b4ed375d..ae9788e56d 100644 --- a/django/utils/translation.py +++ b/django/utils/translation.py @@ -247,7 +247,7 @@ def ngettext(singular, plural, number): return t.ngettext(singular, plural, number) if _default is None: from django.conf import settings - _default = translation('*', settings.LANGUAGE_CODE) + _default = translation(settings.LANGUAGE_CODE) return _default.ngettext(singular, plural, number) gettext_lazy = lazy(gettext, str)