1
0
mirror of https://github.com/django/django.git synced 2025-07-05 18:29:11 +00:00

queryset-refactor: Merged from trunk up to [7122].

git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7124 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-02-16 06:57:52 +00:00
parent 770d587314
commit 2d0588548e
25 changed files with 4555 additions and 90 deletions

View File

@ -168,6 +168,7 @@ answer newbie questions, and generally made Django that much better:
Rob Hudson <http://rob.cogit8.org/>
Jason Huggins <http://www.jrandolph.com/blog/>
Hyun Mi Ae
Ibon <ibonso@gmail.com>
Tom Insam
Baurzhan Ismagulov <ibr@radix50.net>
james_027@yahoo.com

View File

@ -48,6 +48,7 @@ LANGUAGES = (
('en', gettext_noop('English')),
('es', gettext_noop('Spanish')),
('es-ar', gettext_noop('Argentinean Spanish')),
('eu', gettext_noop('Basque')),
('fa', gettext_noop('Persian')),
('fi', gettext_noop('Finnish')),
('fr', gettext_noop('French')),

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,117 @@
# Spanish translation for the django-admin JS files.
# Copyright (C)
# This file is distributed under the same license as the PACKAGE package.
#
msgid ""
msgstr ""
"Project-Id-Version: Django JavaScript 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-07-14 13:47-0500\n"
"PO-Revision-Date: 2007-07-14 13:41-0500\n"
"Last-Translator: Jorge Gajon <gajon@gajon.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: contrib/admin/media/js/calendar.js:24
#: contrib/admin/media/js/dateparse.js:32
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
"Urtarrila Otsaila Martxoa Apirila Maiatza Ekaina Uztaila Abuztua Iraila Urria "
"Azaroa Abendua"
#: contrib/admin/media/js/calendar.js:25
msgid "S M T W T F S"
msgstr "I A A A O O L"
#: contrib/admin/media/js/dateparse.js:33
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
msgstr "Igandea Astelehene Asteartea Asteazkena Osteguna Ostirala Larunbata"
#: contrib/admin/media/js/SelectFilter2.js:33
#, perl-format
msgid "Available %s"
msgstr "%s Erabilgarri"
#: contrib/admin/media/js/SelectFilter2.js:41
msgid "Choose all"
msgstr "Denak aukeratu"
#: contrib/admin/media/js/SelectFilter2.js:46
msgid "Add"
msgstr "Gehitu"
#: contrib/admin/media/js/SelectFilter2.js:48
msgid "Remove"
msgstr "Ezabatu"
#: contrib/admin/media/js/SelectFilter2.js:53
#, perl-format
msgid "Chosen %s"
msgstr "%s Aukeratuak"
#: contrib/admin/media/js/SelectFilter2.js:54
msgid "Select your choice(s) and click "
msgstr "Egin zure aukerak eta click egin "
#: contrib/admin/media/js/SelectFilter2.js:59
msgid "Clear all"
msgstr "Denak garbitu"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
msgid "Now"
msgstr "Orain"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
msgid "Clock"
msgstr "Erlojua"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
msgid "Choose a time"
msgstr "Aukeratu ordu bat"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
msgid "Midnight"
msgstr "Gauerdia"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
msgid "6 a.m."
msgstr "6 a.m."
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
msgid "Noon"
msgstr "Eguerdia"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
msgid "Cancel"
msgstr "Atzera"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
msgid "Today"
msgstr "Gaur"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
msgid "Calendar"
msgstr "Egutegia"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
msgid "Yesterday"
msgstr "Atzo"
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
msgid "Tomorrow"
msgstr "Bihar"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
msgid "Show"
msgstr "Erakutsi"
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
msgid "Hide"
msgstr "Izkutatu"

View File

@ -1,7 +1,7 @@
from django.core.management.base import AppCommand
class Command(AppCommand):
help = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)."
help = "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s)."
output_transaction = True

View File

@ -41,7 +41,9 @@ class ModelBase(type):
# Build complete list of parents
for base in parents:
if base is not Model:
# Things without _meta aren't functional models, so they're
# uninteresting parents.
if hasattr(base, '_meta'):
new_class._meta.parents.append(base)
new_class._meta.parents.extend(base._meta.parents)
@ -139,7 +141,7 @@ class Model(object):
# There is a rather weird disparity here; if kwargs, it's set, then args
# overrides it. It should be one or the other; don't duplicate the work
# The reason for the kwargs check is that standard iterator passes in by
# args, and nstantiation for iteration is 33% faster.
# args, and instantiation for iteration is 33% faster.
args_len = len(args)
if args_len > len(self._meta.fields):
# Daft, but matches old exception sans the err msg.

View File

@ -22,23 +22,40 @@ def pretty_name(name):
name = name[0].upper() + name[1:]
return name.replace('_', ' ')
def get_declared_fields(bases, attrs, with_base_fields=True):
"""
Create a list of form field instances from the passed in 'attrs', plus any
similar fields on the base classes (in 'bases'). This is used by both the
Form and ModelForm metclasses.
If 'with_base_fields' is True, all fields from the bases are used.
Otherwise, only fields in the 'declared_fields' attribute on the bases are
used. The distinction is useful in ModelForm subclassing.
"""
fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
# If this class is subclassing another Form, add that Form's fields.
# Note that we loop over the bases in *reverse*. This is necessary in
# order to preserve the correct order of fields.
if with_base_fields:
for base in bases[::-1]:
if hasattr(base, 'base_fields'):
fields = base.base_fields.items() + fields
else:
for base in bases[::-1]:
if hasattr(base, 'declared_fields'):
fields = base.declared_fields.items() + fields
return SortedDict(fields)
class DeclarativeFieldsMetaclass(type):
"""
Metaclass that converts Field attributes to a dictionary called
'base_fields', taking into account parent class 'base_fields' as well.
"""
def __new__(cls, name, bases, attrs):
fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
# If this class is subclassing another Form, add that Form's fields.
# Note that we loop over the bases in *reverse*. This is necessary in
# order to preserve the correct order of fields.
for base in bases[::-1]:
if hasattr(base, 'base_fields'):
fields = base.base_fields.items() + fields
attrs['base_fields'] = SortedDict(fields)
attrs['base_fields'] = get_declared_fields(bases, attrs)
return type.__new__(cls, name, bases, attrs)
class BaseForm(StrAndUnicode):

View File

@ -11,7 +11,7 @@ from django.utils.datastructures import SortedDict
from django.core.exceptions import ImproperlyConfigured
from util import ValidationError, ErrorList
from forms import BaseForm
from forms import BaseForm, get_declared_fields
from fields import Field, ChoiceField, EMPTY_VALUES
from widgets import Select, SelectMultiple, MultipleHiddenInput
@ -211,57 +211,39 @@ class ModelFormOptions(object):
self.fields = getattr(options, 'fields', None)
self.exclude = getattr(options, 'exclude', None)
class ModelFormMetaclass(type):
def __new__(cls, name, bases, attrs,
formfield_callback=lambda f: f.formfield()):
fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)]
fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter))
try:
parents = [b for b in bases if issubclass(b, ModelForm)]
except NameError:
# We are defining ModelForm itself.
parents = None
if not parents:
return super(ModelFormMetaclass, cls).__new__(cls, name, bases,
attrs)
# If this class is subclassing another Form, add that Form's fields.
# Note that we loop over the bases in *reverse*. This is necessary in
# order to preserve the correct order of fields.
for base in bases[::-1]:
if hasattr(base, 'base_fields'):
fields = base.base_fields.items() + fields
declared_fields = SortedDict(fields)
opts = ModelFormOptions(attrs.get('Meta', None))
attrs['_meta'] = opts
# Don't allow more than one Meta model definition in bases. The fields
# would be generated correctly, but the save method won't deal with
# more than one object.
base_models = []
for base in bases:
base_opts = getattr(base, '_meta', None)
base_model = getattr(base_opts, 'model', None)
if base_model is not None:
base_models.append(base_model)
if len(base_models) > 1:
raise ImproperlyConfigured("%s's base classes define more than one model." % name)
# If a model is defined, extract form fields from it and add them to base_fields
if attrs['_meta'].model is not None:
# Don't allow a subclass to define a different Meta model than a
# parent class has. Technically the right fields would be generated,
# but the save method will not deal with more than one model.
for base in bases:
base_opts = getattr(base, '_meta', None)
base_model = getattr(base_opts, 'model', None)
if base_model and base_model is not opts.model:
raise ImproperlyConfigured('%s defines a different model than its parent.' % name)
model_fields = fields_for_model(opts.model, opts.fields,
opts.exclude, formfield_callback)
# fields declared in base classes override fields from the model
model_fields.update(declared_fields)
attrs['base_fields'] = model_fields
new_class = type.__new__(cls, name, bases, attrs)
declared_fields = get_declared_fields(bases, attrs, False)
opts = new_class._meta = ModelFormOptions(getattr(new_class, 'Meta', None))
if opts.model:
# If a model is defined, extract form fields from it.
fields = fields_for_model(opts.model, opts.fields,
opts.exclude, formfield_callback)
# Override default model fields with any custom declared ones
# (plus, include all the other declared fields).
fields.update(declared_fields)
else:
attrs['base_fields'] = declared_fields
return type.__new__(cls, name, bases, attrs)
fields = declared_fields
new_class.declared_fields = declared_fields
new_class.base_fields = fields
return new_class
class BaseModelForm(BaseForm):
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
initial=None, error_class=ErrorList, label_suffix=':', instance=None):
initial=None, error_class=ErrorList, label_suffix=':',
instance=None):
opts = self._meta
if instance is None:
# if we didn't get an instance, instantiate a new one
@ -277,7 +259,8 @@ class BaseModelForm(BaseForm):
def save(self, commit=True):
"""
Saves this ``form``'s cleaned_data into model instance ``self.instance``.
Saves this ``form``'s cleaned_data into model instance
``self.instance``.
If commit=True, then the changes to ``instance`` will be saved to the
database. Returns ``instance``.

View File

@ -3,7 +3,7 @@ class MergeDict(object):
A simple class for creating new "virtual" dictionaries that actually look
up values in more than one dictionary, passed in the constructor.
If a key appears in more than one of the passed in dictionaries, only the
If a key appears in more than one of the given dictionaries, only the
first occurrence will be used.
"""
def __init__(self, *dicts):

View File

@ -88,7 +88,7 @@ change:
API changes may be necessary.
- Generic relations will most likely be moved out of core and into the
content-types contrib package to avoid core dependancies on optional
content-types contrib package to avoid core dependencies on optional
components.
- The comments framework, which is yet undocumented, will likely get a complete

View File

@ -215,7 +215,7 @@ each ``TaggedItem`` will have a ``content_object`` field that returns the
object it's related to, and you can also assign to that field or use it when
creating a ``TaggedItem``::
>>> from django.contrib.models.auth import User
>>> from django.contrib.auth.models import User
>>> guido = User.objects.get(username='Guido')
>>> t = TaggedItem(content_object=guido, tag='bdfl')
>>> t.save()
@ -235,7 +235,7 @@ a "reverse" generic relationship to enable an additional API. For example::
``Bookmark`` instances will each have a ``tags`` attribute, which can
be used to retrieve their associated ``TaggedItems``::
>>> b = Bookmark('http://www.djangoproject.com/')
>>> b = Bookmark(url='http://www.djangoproject.com/')
>>> b.save()
>>> t1 = TaggedItem(content_object=b, tag='django')
>>> t1.save()

View File

@ -5,7 +5,7 @@ Third-party distributions of Django
Several third-party distributors are now providing versions of Django integrated
with their package-management systems. These can make installation and upgrading
much easier for users of Django since the integration includes the ability to
automatically install dependancies (like database adapters) that Django
automatically install dependencies (like database adapters) that Django
requires.
Typically, these packages are based on the latest stable release of Django, so

View File

@ -717,7 +717,7 @@ in Python package syntax, e.g. ``mysite.settings``. If this isn't provided,
variable.
Note that this option is unnecessary in ``manage.py``, because it uses
``settings.py`` from the current project by default.
``settings.py`` from the current project by default.
Extra niceties
==============
@ -765,9 +765,9 @@ a command that can be executed as an action when you run ``manage.py``::
__init__.py
explode.py
views.py
In this example, the ``explode`` command will be made available to any project
that includes the ``fancy_blog`` application in ``settings.INSTALLED_APPS``.
that includes the ``blog`` application in ``settings.INSTALLED_APPS``.
The ``explode.py`` module has only one requirement -- it must define a class
called ``Command`` that extends ``django.core.management.base.BaseCommand``.

View File

@ -138,7 +138,7 @@ Installing a distribution-specific package
Check the `distribution specific notes`_ to see if your
platform/distribution provides official Django packages/installers.
Distribution-provided packages will typically allow for automatic
installation of dependancies and easy upgrade paths.
installation of dependencies and easy upgrade paths.
Installing an official release
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -384,7 +384,7 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
``IPAddressField``
~~~~~~~~~~~~~~~~~~
An IP address, in string format (i.e. "24.124.1.30").
An IP address, in string format (e.g. "192.0.2.30").
The admin represents this as an ``<input type="text">`` (a single-line input).
@ -952,10 +952,10 @@ the relationship should work. All are optional:
``limit_choices_to`` See the description under ``ForeignKey`` above.
``symmetrical`` Only used in the definition of ManyToManyFields on self.
Consider the following model:
Consider the following model::
class Person(models.Model):
friends = models.ManyToManyField("self")
class Person(models.Model):
friends = models.ManyToManyField("self")
When Django processes this model, it identifies that it has
a ``ManyToManyField`` on itself, and as a result, it
@ -1871,7 +1871,7 @@ more simply as::
If you define a ``__unicode__()`` method on your model and not a ``__str__()``
method, Django will automatically provide you with a ``__str__()`` that calls
``__unicode()__`` and then converts the result correctly to a UTF-8 encoded
``__unicode__()`` and then converts the result correctly to a UTF-8 encoded
string object. This is recommended development practice: define only
``__unicode__()`` and let Django take care of the conversion to string objects
when required.

View File

@ -320,3 +320,41 @@ parameter when declaring the form field::
...
... class Meta:
... model = Article
Form inheritance
----------------
As with basic forms, you can extend and reuse ``ModelForms`` by inheriting
them. This is useful if you need to declare extra fields or extra methods on a
parent class for use in a number of forms derived from models. For example,
using the previous ``ArticleForm`` class::
>>> class EnhancedArticleForm(ArticleForm):
... def clean_pub_date(self):
... ...
This creates a form that behaves identically to ``ArticleForm``, except there's
some extra validation and cleaning for the ``pub_date`` field.
You can also subclass the parent's ``Meta`` inner class if you want to change
the ``Meta.fields`` or ``Meta.excludes`` lists::
>>> class RestrictedArticleForm(EnhancedArticleForm):
... class Meta(ArticleForm.Meta):
... exclude = ['body']
This adds the extra method from the ``EnhancedArticleForm`` and modifies
the original ``ArticleForm.Meta`` to remove one field.
There are a couple of things to note, however.
* Normal Python name resolution rules apply. If you have multiple base
classes that declare a ``Meta`` inner class, only the first one will be
used. This means the child's ``Meta``, if it exists, otherwise the
``Meta`` of the first parent, etc.
* For technical reasons, a subclass cannot inherit from both a ``ModelForm``
and a ``Form`` simultaneously.
Chances are these notes won't affect you unless you're trying to do something
tricky with subclassing.

View File

@ -576,7 +576,7 @@ Three things to note about 404 views:
in the 404.
* The 404 view is passed a ``RequestContext`` and will have access to
variables supplied by your ``TEMPLATE_CONTEXT_PROCESSORS`` (e.g.
variables supplied by your ``TEMPLATE_CONTEXT_PROCESSORS`` setting (e.g.,
``MEDIA_URL``).
* If ``DEBUG`` is set to ``True`` (in your settings module), then your 404

View File

@ -30,9 +30,9 @@ Optional arguments
``context_instance``
The context instance to render the template with. By default, the template
will be rendered with a ``Context`` instance (filled with values from
``dictionary``). If you need to use `context processors`_, you will want to
render the template with a ``RequestContext`` instance instead. Your code
might look something like this::
``dictionary``). If you need to use `context processors`_, render the
template with a ``RequestContext`` instance instead. Your code might look
something like this::
return render_to_response('my_template.html',
my_data_dictionary,

View File

@ -1406,6 +1406,8 @@ Joins a list with a string, like Python's ``str.join(list)``.
last
~~~~
**New in Django development version.**
Returns the last item in a list.
length

View File

@ -190,6 +190,28 @@ The remaining arguments should be tuples in this format::
...where ``optional dictionary`` and ``optional name`` are optional. (See
`Passing extra options to view functions`_ below.)
.. note::
Because `patterns()` is a function call, it accepts a maximum of 255
arguments (URL patterns, in this case). This is a limit for all Python
function calls. This is rarely a problem in practice, because you'll
typically structure your URL patterns modularly by using `include()`
sections. However, on the off-chance you do hit the 255-argument limit,
realize that `patterns()` returns a Python list, so you can split up the
construction of the list.
::
urlpatterns = patterns('',
...
)
urlpatterns += patterns('',
...
)
Python lists have unlimited size, so there's no limit to how many URL
patterns you can construct. The only limit is that you can only create 254
at a time (the 255th argument is the initial prefix argument).
url
---

View File

@ -64,11 +64,11 @@ class TextFile(models.Model):
def __unicode__(self):
return self.description
class ImageFile(models.Model):
description = models.CharField(max_length=20)
image = models.FileField(upload_to=tempfile.gettempdir())
def __unicode__(self):
return self.description
@ -155,29 +155,52 @@ familiar with the mechanics.
... class Meta:
... model = Category
>>> class BadForm(CategoryForm):
>>> class OddForm(CategoryForm):
... class Meta:
... model = Article
Traceback (most recent call last):
...
ImproperlyConfigured: BadForm defines a different model than its parent.
OddForm is now an Article-related thing, because BadForm.Meta overrides
CategoryForm.Meta.
>>> OddForm.base_fields.keys()
['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories']
>>> class ArticleForm(ModelForm):
... class Meta:
... model = Article
First class with a Meta class wins.
>>> class BadForm(ArticleForm, CategoryForm):
... pass
Traceback (most recent call last):
...
ImproperlyConfigured: BadForm's base classes define more than one model.
>>> OddForm.base_fields.keys()
['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories']
This one is OK since the subclass specifies the same model as the parent.
Subclassing without specifying a Meta on the class will use the parent's Meta
(or the first parent in the MRO if there are multiple parent classes).
>>> class SubCategoryForm(CategoryForm):
>>> class CategoryForm(ModelForm):
... class Meta:
... model = Category
>>> class SubCategoryForm(CategoryForm):
... pass
>>> SubCategoryForm.base_fields.keys()
['name', 'slug', 'url']
We can also subclass the Meta inner class to change the fields list.
>>> class CategoryForm(ModelForm):
... checkbox = forms.BooleanField()
...
... class Meta:
... model = Category
>>> class SubCategoryForm(CategoryForm):
... class Meta(CategoryForm.Meta):
... exclude = ['url']
>>> print SubCategoryForm()
<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr>
<tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr>
<tr><th><label for="id_checkbox">Checkbox:</label></th><td><input type="checkbox" name="checkbox" id="id_checkbox" /></td></tr>
# Old form_for_x tests #######################################################

View File

@ -2,8 +2,8 @@
6. Specifying ordering
Specify default ordering for a model using the ``ordering`` attribute, which
should be a list or tuple of field names. This tells Django how to order the
results of ``get_list()`` and other similar functions.
should be a list or tuple of field names. This tells Django how to order
queryset results.
If a field name in ``ordering`` starts with a hyphen, that field will be
ordered in descending order. Otherwise, it'll be ordered in ascending order.

View File

@ -1,3 +1,5 @@
import sys
tests = """
>>> from django.utils.translation.trans_real import parse_accept_lang_header
>>> p = parse_accept_lang_header
@ -83,7 +85,14 @@ source tree.
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'}
>>> g(r)
'es-ar'
"""
# Python 2.3 returns slightly different results for completely bogus locales,
# so we omit this test for that anything below 2.4. It's relatively harmless in
# any cases (GIGO). This also means this won't be executed on Jython currently,
# but life's like that sometimes.
if sys.version_info >= (2, 4):
tests += """
This test assumes there won't be a Django translation to a US variation
of the Spanish language, a safe assumption. When the user sets it
as the preferred language, the main 'es' translation should be selected
@ -91,7 +100,9 @@ instead.
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'}
>>> g(r)
'es'
"""
tests += """
This tests the following scenario: there isn't a main language (zh)
translation of Django but there is a translation to variation (zh_CN)
the user sets zh-cn as the preferred language, it should be selected by