mirror of
https://github.com/django/django.git
synced 2025-07-04 01:39:20 +00:00
Merged to [4656]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@4657 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
811163d24e
commit
b0bbdc744d
1
AUTHORS
1
AUTHORS
@ -118,6 +118,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
konrad@gwu.edu
|
konrad@gwu.edu
|
||||||
lakin.wecker@gmail.com
|
lakin.wecker@gmail.com
|
||||||
Stuart Langridge <http://www.kryogenix.org/>
|
Stuart Langridge <http://www.kryogenix.org/>
|
||||||
|
Nicola Larosa <nico@teknico.net>
|
||||||
Eugene Lazutkin <http://lazutkin.com/blog/>
|
Eugene Lazutkin <http://lazutkin.com/blog/>
|
||||||
Jeong-Min Lee <falsetru@gmail.com>
|
Jeong-Min Lee <falsetru@gmail.com>
|
||||||
Christopher Lenz <http://www.cmlenz.net/>
|
Christopher Lenz <http://www.cmlenz.net/>
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,20 +1,39 @@
|
|||||||
|
# translation of djangojs.po to Italiano
|
||||||
# Italian translation for the django-admin JS files
|
# Italian translation for the django-admin JS files
|
||||||
# Copyright (C) 2006 the Lawrence Journal-World
|
# Copyright (C) 2006 the Lawrence Journal-World
|
||||||
# This file is distributed under the same license as the Django package.
|
# This file is distributed under the same license as the Django package.
|
||||||
# Carlo C8E Miron <carlo.miron AT gmail.com>, 2006.
|
|
||||||
#
|
#
|
||||||
|
# Carlo C8E Miron <carlo.miron AT gmail.com>, 2006.
|
||||||
|
# Nicola 'tekNico' Larosa <nico@tekNico.net>, 2007.
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Django JavaScript 1.0\n"
|
"Project-Id-Version: djangojs\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
"POT-Creation-Date: 2007-02-26 20:46+0100\n"
|
||||||
"PO-Revision-Date: 2005-12-04 21:47+0100\n"
|
"PO-Revision-Date: 2007-02-26 20:55+0100\n"
|
||||||
"Last-Translator: Carlo C8E Miron <carlo.miron AT gmail.com>\n"
|
"Last-Translator: Nicola Larosa <nico@tekNico.net>\n"
|
||||||
"Language-Team: Italian <Django-I18N@googlegroups.com>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: KBabel 1.11.2\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 ""
|
||||||
|
"Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settembre Ottobre "
|
||||||
|
"Novembre Dicembre"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/calendar.js:25
|
||||||
|
msgid "S M T W T F S"
|
||||||
|
msgstr "D L M M G V S"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/dateparse.js:33
|
||||||
|
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||||
|
msgstr "Domenica Lunedì Martedì Mercoledì Giovedì Venerdì Sabato"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||||
#, perl-format
|
#, perl-format
|
||||||
@ -23,7 +42,7 @@ msgstr "Disponibile %s"
|
|||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||||
msgid "Choose all"
|
msgid "Choose all"
|
||||||
msgstr "Seleziona tutto"
|
msgstr "Scegli tutto"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||||
msgid "Add"
|
msgid "Add"
|
||||||
@ -36,7 +55,7 @@ msgstr "Rimuovi"
|
|||||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||||
#, perl-format
|
#, perl-format
|
||||||
msgid "Chosen %s"
|
msgid "Chosen %s"
|
||||||
msgstr "Selezionato %s"
|
msgstr "Scelto %s"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||||
msgid "Select your choice(s) and click "
|
msgid "Select your choice(s) and click "
|
||||||
@ -46,66 +65,59 @@ msgstr "Seleziona le tue scelte e clicca "
|
|||||||
msgid "Clear all"
|
msgid "Clear all"
|
||||||
msgstr "Cancella tutto"
|
msgstr "Cancella tutto"
|
||||||
|
|
||||||
#: contrib/admin/media/js/dateparse.js:26
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||||
#: contrib/admin/media/js/calendar.js:24
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||||
msgid ""
|
|
||||||
"January February March April May June July August September October November "
|
|
||||||
"December"
|
|
||||||
msgstr ""
|
|
||||||
"Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settembre Ottobre "
|
|
||||||
"Novembre Dicembre"
|
|
||||||
|
|
||||||
#: contrib/admin/media/js/dateparse.js:27
|
|
||||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
|
||||||
msgstr "Domenica Lunedì Martedì Mercoledì Giovedì Venerdì Sabato"
|
|
||||||
|
|
||||||
#: contrib/admin/media/js/calendar.js:25
|
|
||||||
msgid "S M T W T F S"
|
|
||||||
msgstr "D L M M G V S"
|
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
|
||||||
msgid "Now"
|
msgid "Now"
|
||||||
msgstr "Adesso"
|
msgstr "Adesso"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||||
msgid "Clock"
|
msgid "Clock"
|
||||||
msgstr "Orologio"
|
msgstr "Orologio"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||||
msgid "Choose a time"
|
msgid "Choose a time"
|
||||||
msgstr "Seleziona un orario"
|
msgstr "Scegli un orario"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||||
msgid "Midnight"
|
msgid "Midnight"
|
||||||
msgstr "Mezzanotte"
|
msgstr "Mezzanotte"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||||
msgid "6 a.m."
|
msgid "6 a.m."
|
||||||
msgstr "6 del mattino"
|
msgstr "6 del mattino"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||||
msgid "Noon"
|
msgid "Noon"
|
||||||
msgstr "Mezzogiorno"
|
msgstr "Mezzogiorno"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annulla"
|
msgstr "Annulla"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||||
msgid "Today"
|
msgid "Today"
|
||||||
msgstr "Oggi"
|
msgstr "Oggi"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||||
msgid "Calendar"
|
msgid "Calendar"
|
||||||
msgstr "Calendario"
|
msgstr "Calendario"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||||
msgid "Yesterday"
|
msgid "Yesterday"
|
||||||
msgstr "Ieri"
|
msgstr "Ieri"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||||
msgid "Tomorrow"
|
msgid "Tomorrow"
|
||||||
msgstr "Domani"
|
msgstr "Domani"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||||
|
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||||
|
msgid "Show"
|
||||||
|
msgstr "Mostra"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||||
|
msgid "Hide"
|
||||||
|
msgstr "Nascondi"
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ form .form-row p { padding-left:0; font-size:11px; }
|
|||||||
/* FORM LABELS */
|
/* FORM LABELS */
|
||||||
form h4 { margin:0 !important; padding:0 !important; border:none !important; }
|
form h4 { margin:0 !important; padding:0 !important; border:none !important; }
|
||||||
label { font-weight:normal !important; color:#666; font-size:12px; }
|
label { font-weight:normal !important; color:#666; font-size:12px; }
|
||||||
/* label.inline { margin-left:20px; } */
|
label.inline { margin-left:20px; }
|
||||||
.required label, label.required { font-weight:bold !important; color:#333 !important; }
|
.required label, label.required { font-weight:bold !important; color:#333 !important; }
|
||||||
|
|
||||||
/* RADIO BUTTONS */
|
/* RADIO BUTTONS */
|
||||||
@ -20,7 +20,7 @@ form ul.inline li { float:left; padding-right:7px; }
|
|||||||
|
|
||||||
/* ALIGNED FIELDSETS */
|
/* ALIGNED FIELDSETS */
|
||||||
.aligned label { display:block; padding:0 1em 3px 0; float:left; width:8em; }
|
.aligned label { display:block; padding:0 1em 3px 0; float:left; width:8em; }
|
||||||
/* .aligned label.inline { display:inline; float:none; } */
|
.aligned label.inline { display:inline; float:none; }
|
||||||
.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width:350px; }
|
.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width:350px; }
|
||||||
form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; }
|
form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; }
|
||||||
form .aligned table p { margin-left:0; padding-left:0; }
|
form .aligned table p { margin-left:0; padding-left:0; }
|
||||||
|
@ -84,6 +84,7 @@ class QuerySet(object):
|
|||||||
self._filters = Q()
|
self._filters = Q()
|
||||||
self._order_by = None # Ordering, e.g. ('date', '-name'). If None, use model's ordering.
|
self._order_by = None # Ordering, e.g. ('date', '-name'). If None, use model's ordering.
|
||||||
self._select_related = False # Whether to fill cache for related objects.
|
self._select_related = False # Whether to fill cache for related objects.
|
||||||
|
self._max_related_depth = 0 # Maximum "depth" for select_related
|
||||||
self._distinct = False # Whether the query should use SELECT DISTINCT.
|
self._distinct = False # Whether the query should use SELECT DISTINCT.
|
||||||
self._select = {} # Dictionary of attname -> SQL.
|
self._select = {} # Dictionary of attname -> SQL.
|
||||||
self._where = [] # List of extra WHERE clauses to use.
|
self._where = [] # List of extra WHERE clauses to use.
|
||||||
@ -186,7 +187,8 @@ class QuerySet(object):
|
|||||||
raise StopIteration
|
raise StopIteration
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if fill_cache:
|
if fill_cache:
|
||||||
obj, index_end = get_cached_row(self.model, row, 0)
|
obj, index_end = get_cached_row(klass=self.model, row=row,
|
||||||
|
index_start=0, max_depth=self._max_related_depth)
|
||||||
else:
|
else:
|
||||||
obj = self.model(*row[:index_end])
|
obj = self.model(*row[:index_end])
|
||||||
for i, k in enumerate(extra_select):
|
for i, k in enumerate(extra_select):
|
||||||
@ -394,9 +396,9 @@ class QuerySet(object):
|
|||||||
else:
|
else:
|
||||||
return self._filter_or_exclude(None, **filter_obj)
|
return self._filter_or_exclude(None, **filter_obj)
|
||||||
|
|
||||||
def select_related(self, true_or_false=True):
|
def select_related(self, true_or_false=True, depth=0):
|
||||||
"Returns a new QuerySet instance with '_select_related' modified."
|
"Returns a new QuerySet instance with '_select_related' modified."
|
||||||
return self._clone(_select_related=true_or_false)
|
return self._clone(_select_related=true_or_false, _max_related_depth=depth)
|
||||||
|
|
||||||
def order_by(self, *field_names):
|
def order_by(self, *field_names):
|
||||||
"Returns a new QuerySet instance with the ordering changed."
|
"Returns a new QuerySet instance with the ordering changed."
|
||||||
@ -430,6 +432,7 @@ class QuerySet(object):
|
|||||||
c._filters = self._filters
|
c._filters = self._filters
|
||||||
c._order_by = self._order_by
|
c._order_by = self._order_by
|
||||||
c._select_related = self._select_related
|
c._select_related = self._select_related
|
||||||
|
c._max_related_depth = self._max_related_depth
|
||||||
c._distinct = self._distinct
|
c._distinct = self._distinct
|
||||||
c._select = self._select.copy()
|
c._select = self._select.copy()
|
||||||
c._where = self._where[:]
|
c._where = self._where[:]
|
||||||
@ -483,7 +486,10 @@ class QuerySet(object):
|
|||||||
|
|
||||||
# Add additional tables and WHERE clauses based on select_related.
|
# Add additional tables and WHERE clauses based on select_related.
|
||||||
if self._select_related:
|
if self._select_related:
|
||||||
fill_table_cache(opts, select, tables, where, opts.db_table, [opts.db_table])
|
fill_table_cache(opts, select, tables, where,
|
||||||
|
old_prefix=opts.db_table,
|
||||||
|
cache_tables_seen=[opts.db_table],
|
||||||
|
max_depth=self._max_related_depth)
|
||||||
|
|
||||||
# Add any additional SELECTs.
|
# Add any additional SELECTs.
|
||||||
if self._select:
|
if self._select:
|
||||||
@ -728,21 +734,33 @@ def get_where_clause(lookup_type, table_prefix, field_name, value):
|
|||||||
return backend.get_fulltext_search_sql(table_prefix + field_name)
|
return backend.get_fulltext_search_sql(table_prefix + field_name)
|
||||||
raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
|
raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
|
||||||
|
|
||||||
def get_cached_row(klass, row, index_start):
|
def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0):
|
||||||
"Helper function that recursively returns an object with cache filled"
|
"""Helper function that recursively returns an object with cache filled"""
|
||||||
|
|
||||||
|
# If we've got a max_depth set and we've exceeded that depth, bail now.
|
||||||
|
if max_depth and cur_depth > max_depth:
|
||||||
|
return None
|
||||||
|
|
||||||
index_end = index_start + len(klass._meta.fields)
|
index_end = index_start + len(klass._meta.fields)
|
||||||
obj = klass(*row[index_start:index_end])
|
obj = klass(*row[index_start:index_end])
|
||||||
for f in klass._meta.fields:
|
for f in klass._meta.fields:
|
||||||
if f.rel and not f.null:
|
if f.rel and not f.null:
|
||||||
rel_obj, index_end = get_cached_row(f.rel.to, row, index_end)
|
cached_row = get_cached_row(f.rel.to, row, index_end, max_depth, cur_depth+1)
|
||||||
setattr(obj, f.get_cache_name(), rel_obj)
|
if cached_row:
|
||||||
|
rel_obj, index_end = cached_row
|
||||||
|
setattr(obj, f.get_cache_name(), rel_obj)
|
||||||
return obj, index_end
|
return obj, index_end
|
||||||
|
|
||||||
def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen):
|
def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen, max_depth=0, cur_depth=0):
|
||||||
"""
|
"""
|
||||||
Helper function that recursively populates the select, tables and where (in
|
Helper function that recursively populates the select, tables and where (in
|
||||||
place) for select_related queries.
|
place) for select_related queries.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# If we've got a max_depth set and we've exceeded that depth, bail now.
|
||||||
|
if max_depth and cur_depth > max_depth:
|
||||||
|
return None
|
||||||
|
|
||||||
qn = backend.quote_name
|
qn = backend.quote_name
|
||||||
for f in opts.fields:
|
for f in opts.fields:
|
||||||
if f.rel and not f.null:
|
if f.rel and not f.null:
|
||||||
@ -757,7 +775,7 @@ def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen)
|
|||||||
where.append('%s.%s = %s.%s' % \
|
where.append('%s.%s = %s.%s' % \
|
||||||
(qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column)))
|
(qn(old_prefix), qn(f.column), qn(db_table), qn(f.rel.get_related_field().column)))
|
||||||
select.extend(['%s.%s' % (qn(db_table), qn(f2.column)) for f2 in f.rel.to._meta.fields])
|
select.extend(['%s.%s' % (qn(db_table), qn(f2.column)) for f2 in f.rel.to._meta.fields])
|
||||||
fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen)
|
fill_table_cache(f.rel.to._meta, select, tables, where, db_table, cache_tables_seen, max_depth, cur_depth+1)
|
||||||
|
|
||||||
def parse_lookup(kwarg_items, opts):
|
def parse_lookup(kwarg_items, opts):
|
||||||
# Helper function that handles converting API kwargs
|
# Helper function that handles converting API kwargs
|
||||||
|
@ -16,7 +16,7 @@ from django.utils.tzinfo import LocalTimezone
|
|||||||
from calendar import isleap, monthrange
|
from calendar import isleap, monthrange
|
||||||
import re, time
|
import re, time
|
||||||
|
|
||||||
re_formatchars = re.compile(r'(?<!\\)([aABdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])')
|
re_formatchars = re.compile(r'(?<!\\)([aAbBdDfFgGhHiIjlLmMnNOPrsStTUwWyYzZ])')
|
||||||
re_escaped = re.compile(r'\\(.)')
|
re_escaped = re.compile(r'\\(.)')
|
||||||
|
|
||||||
class Formatter(object):
|
class Formatter(object):
|
||||||
@ -110,6 +110,10 @@ class DateFormat(TimeFormat):
|
|||||||
if hasattr(self.data, 'hour') and not self.timezone:
|
if hasattr(self.data, 'hour') and not self.timezone:
|
||||||
self.timezone = LocalTimezone(dt)
|
self.timezone = LocalTimezone(dt)
|
||||||
|
|
||||||
|
def b(self):
|
||||||
|
"Month, textual, 3 letters, lowercase; e.g. 'jan'"
|
||||||
|
return MONTHS_3[self.data.month]
|
||||||
|
|
||||||
def d(self):
|
def d(self):
|
||||||
"Day of the month, 2 digits with leading zeros; i.e. '01' to '31'"
|
"Day of the month, 2 digits with leading zeros; i.e. '01' to '31'"
|
||||||
return '%02d' % self.data.day
|
return '%02d' % self.data.day
|
||||||
|
@ -398,7 +398,7 @@ To do this, add the following line to your URLconf::
|
|||||||
|
|
||||||
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
||||||
|
|
||||||
Here's what ``django.contrib.auth.views.login`` does::
|
Here's what ``django.contrib.auth.views.login`` does:
|
||||||
|
|
||||||
* If called via ``GET``, it displays a login form that POSTs to the same
|
* If called via ``GET``, it displays a login form that POSTs to the same
|
||||||
URL. More on this in a bit.
|
URL. More on this in a bit.
|
||||||
|
@ -596,6 +596,21 @@ related ``Person`` *and* the related ``City``::
|
|||||||
Note that ``select_related()`` does not follow foreign keys that have
|
Note that ``select_related()`` does not follow foreign keys that have
|
||||||
``null=True``.
|
``null=True``.
|
||||||
|
|
||||||
|
Usually, using ``select_related()`` can vastly improve performance because your
|
||||||
|
app can avoid many database calls. However, in situations with deeply nested
|
||||||
|
sets of relationships ``select_related()`` can sometimes end up following "too
|
||||||
|
many" relations, and can generate queries so large that they end up being slow.
|
||||||
|
|
||||||
|
In these situations, you can use the ``depth`` argument to ``select_related()``
|
||||||
|
to control how many "levels" of relations ``select_related()`` will actually
|
||||||
|
follow::
|
||||||
|
|
||||||
|
b = Book.objects.select_related(depth=1).get(id=4)
|
||||||
|
p = b.author # Doesn't hit the database.
|
||||||
|
c = p.hometown # Requires a database call.
|
||||||
|
|
||||||
|
The ``depth`` argument is new in the Django development version.
|
||||||
|
|
||||||
``extra(select=None, where=None, params=None, tables=None)``
|
``extra(select=None, where=None, params=None, tables=None)``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ runfcgi [options]
|
|||||||
-----------------
|
-----------------
|
||||||
Starts a set of FastCGI processes suitable for use with any web server
|
Starts a set of FastCGI processes suitable for use with any web server
|
||||||
which supports the FastCGI protocol. See the `FastCGI deployment
|
which supports the FastCGI protocol. See the `FastCGI deployment
|
||||||
documentation`- for details. Requires the Python FastCGI module from
|
documentation`_ for details. Requires the Python FastCGI module from
|
||||||
`flup`_.
|
`flup`_.
|
||||||
|
|
||||||
.. _FastCGI deployment documentation: ../fastcgi/
|
.. _FastCGI deployment documentation: ../fastcgi/
|
||||||
|
@ -64,7 +64,7 @@ installed.
|
|||||||
.. _PostgreSQL: http://www.postgresql.org/
|
.. _PostgreSQL: http://www.postgresql.org/
|
||||||
.. _MySQL: http://www.mysql.com/
|
.. _MySQL: http://www.mysql.com/
|
||||||
.. _Django's ticket system: http://code.djangoproject.com/report/1
|
.. _Django's ticket system: http://code.djangoproject.com/report/1
|
||||||
.. _psycopg: http://initd.org/projects/psycopg1
|
.. _psycopg: http://initd.org/tracker/psycopg
|
||||||
.. _compiled Windows version: http://stickpeople.com/projects/python/win-psycopg/
|
.. _compiled Windows version: http://stickpeople.com/projects/python/win-psycopg/
|
||||||
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
|
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
|
||||||
.. _SQLite: http://www.sqlite.org/
|
.. _SQLite: http://www.sqlite.org/
|
||||||
|
@ -239,10 +239,10 @@ The cache key prefix that the cache middleware should use. See the
|
|||||||
DATABASE_ENGINE
|
DATABASE_ENGINE
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Default: ``'postgresql'``
|
Default: ``''`` (Empty string)
|
||||||
|
|
||||||
Which database backend to use. Either ``'postgresql'``, ``'mysql'``,
|
Which database backend to use. Either ``'postgresql_psycopg2'``,
|
||||||
``'sqlite3'`` or ``'ado_mssql'``.
|
``'postgresql'``, ``'mysql'``, ``'sqlite3'`` or ``'ado_mssql'``.
|
||||||
|
|
||||||
DATABASE_HOST
|
DATABASE_HOST
|
||||||
-------------
|
-------------
|
||||||
|
@ -645,6 +645,7 @@ Available format strings:
|
|||||||
output, because this includes periods
|
output, because this includes periods
|
||||||
to match Associated Press style.)
|
to match Associated Press style.)
|
||||||
A ``'AM'`` or ``'PM'``. ``'AM'``
|
A ``'AM'`` or ``'PM'``. ``'AM'``
|
||||||
|
b Month, textual, 3 letters, lowercase. ``'jan'``
|
||||||
B Not implemented.
|
B Not implemented.
|
||||||
d Day of the month, 2 digits with ``'01'`` to ``'31'``
|
d Day of the month, 2 digits with ``'01'`` to ``'31'``
|
||||||
leading zeros.
|
leading zeros.
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
#
|
#
|
||||||
# To uninstall, just remove the line from your .bash_profile and .bashrc.
|
# To uninstall, just remove the line from your .bash_profile and .bashrc.
|
||||||
|
|
||||||
|
# Enable extended pattern matching operators.
|
||||||
|
shopt -s extglob
|
||||||
|
|
||||||
_django_completion()
|
_django_completion()
|
||||||
{
|
{
|
||||||
local cur prev opts actions action_shell_opts action_runfcgi_opts
|
local cur prev opts actions action_shell_opts action_runfcgi_opts
|
||||||
@ -58,8 +61,13 @@ _django_completion()
|
|||||||
||
|
||
|
||||||
# python manage.py, /some/path/python manage.py (if manage.py exists)
|
# python manage.py, /some/path/python manage.py (if manage.py exists)
|
||||||
( ${COMP_CWORD} -eq 2 &&
|
( ${COMP_CWORD} -eq 2 &&
|
||||||
( $( basename ${COMP_WORDS[0]} ) == python ) &&
|
( $( basename ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
|
||||||
( $( basename ${COMP_WORDS[1]} ) == manage.py) &&
|
( $( basename ${COMP_WORDS[1]} ) == manage.py) &&
|
||||||
|
( -r ${COMP_WORDS[1]} ) )
|
||||||
|
||
|
||||||
|
( ${COMP_CWORD} -eq 2 &&
|
||||||
|
( $( basename ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
|
||||||
|
( $( basename ${COMP_WORDS[1]} ) == django-admin.py) &&
|
||||||
( -r ${COMP_WORDS[1]} ) ) ]] ; then
|
( -r ${COMP_WORDS[1]} ) ) ]] ; then
|
||||||
|
|
||||||
case ${cur} in
|
case ${cur} in
|
||||||
@ -135,3 +143,17 @@ _django_completion()
|
|||||||
}
|
}
|
||||||
|
|
||||||
complete -F _django_completion django-admin.py manage.py
|
complete -F _django_completion django-admin.py manage.py
|
||||||
|
|
||||||
|
# Support for multiple interpreters.
|
||||||
|
unset pythons
|
||||||
|
if command -v whereis &>/dev/null; then
|
||||||
|
python_interpreters=$(whereis -b python | cut -d " " -f 2-)
|
||||||
|
for python in $python_interpreters; do
|
||||||
|
pythons="${pythons} $(basename $python)"
|
||||||
|
done
|
||||||
|
pythons=$(echo $pythons | tr " " "\n" | sort -u | tr "\n" " ")
|
||||||
|
else
|
||||||
|
pythons=python
|
||||||
|
fi
|
||||||
|
|
||||||
|
complete -F _django_completion -o default $pythons
|
||||||
|
0
tests/modeltests/select_related/__init__.py
Normal file
0
tests/modeltests/select_related/__init__.py
Normal file
152
tests/modeltests/select_related/models.py
Normal file
152
tests/modeltests/select_related/models.py
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
"""
|
||||||
|
XXX. Tests for ``select_related()``
|
||||||
|
|
||||||
|
``select_related()`` follows all relationships and pre-caches any foreign key
|
||||||
|
values so that complex trees can be fetched in a single query. However, this
|
||||||
|
isn't always a good idea, so the ``depth`` argument control how many "levels"
|
||||||
|
the select-related behavior will traverse.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Who remembers high school biology?
|
||||||
|
|
||||||
|
class Domain(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Kingdom(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
domain = models.ForeignKey(Domain)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Phylum(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
kingdom = models.ForeignKey(Kingdom)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Klass(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
phylum = models.ForeignKey(Phylum)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Order(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
klass = models.ForeignKey(Klass)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Family(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
order = models.ForeignKey(Order)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Genus(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
family = models.ForeignKey(Family)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Species(models.Model):
|
||||||
|
name = models.CharField(maxlength=50)
|
||||||
|
genus = models.ForeignKey(Genus)
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def create_tree(stringtree):
|
||||||
|
"""Helper to create a complete tree"""
|
||||||
|
names = stringtree.split()
|
||||||
|
models = [Domain, Kingdom, Phylum, Klass, Order, Family, Genus, Species]
|
||||||
|
assert len(names) == len(models), (names, models)
|
||||||
|
|
||||||
|
parent = None
|
||||||
|
for name, model in zip(names, models):
|
||||||
|
try:
|
||||||
|
obj = model.objects.get(name=name)
|
||||||
|
except model.DoesNotExist:
|
||||||
|
obj = model(name=name)
|
||||||
|
if parent:
|
||||||
|
setattr(obj, parent.__class__.__name__.lower(), parent)
|
||||||
|
obj.save()
|
||||||
|
parent = obj
|
||||||
|
|
||||||
|
__test__ = {'API_TESTS':"""
|
||||||
|
|
||||||
|
# Set up.
|
||||||
|
# The test runner sets settings.DEBUG to False, but we want to gather queries
|
||||||
|
# so we'll set it to True here and reset it at the end of the test suite.
|
||||||
|
>>> from django.conf import settings
|
||||||
|
>>> settings.DEBUG = True
|
||||||
|
|
||||||
|
>>> create_tree("Eukaryota Animalia Anthropoda Insecta Diptera Drosophilidae Drosophila melanogaster")
|
||||||
|
>>> create_tree("Eukaryota Animalia Chordata Mammalia Primates Hominidae Homo sapiens")
|
||||||
|
>>> create_tree("Eukaryota Plantae Magnoliophyta Magnoliopsida Fabales Fabaceae Pisum sativum")
|
||||||
|
>>> create_tree("Eukaryota Fungi Basidiomycota Homobasidiomycatae Agaricales Amanitacae Amanita muscaria")
|
||||||
|
|
||||||
|
>>> from django import db
|
||||||
|
|
||||||
|
# Normally, accessing FKs doesn't fill in related objects:
|
||||||
|
>>> db.reset_queries()
|
||||||
|
>>> fly = Species.objects.get(name="melanogaster")
|
||||||
|
>>> fly.genus.family.order.klass.phylum.kingdom.domain
|
||||||
|
<Domain: Eukaryota>
|
||||||
|
>>> len(db.connection.queries)
|
||||||
|
8
|
||||||
|
|
||||||
|
# However, a select_related() call will fill in those related objects without any extra queries:
|
||||||
|
>>> db.reset_queries()
|
||||||
|
>>> person = Species.objects.select_related().get(name="sapiens")
|
||||||
|
>>> person.genus.family.order.klass.phylum.kingdom.domain
|
||||||
|
<Domain: Eukaryota>
|
||||||
|
>>> len(db.connection.queries)
|
||||||
|
1
|
||||||
|
|
||||||
|
# select_related() also of course applies to entire lists, not just items.
|
||||||
|
# Without select_related()
|
||||||
|
>>> db.reset_queries()
|
||||||
|
>>> world = Species.objects.all()
|
||||||
|
>>> [o.genus.family for o in world]
|
||||||
|
[<Family: Drosophilidae>, <Family: Hominidae>, <Family: Fabaceae>, <Family: Amanitacae>]
|
||||||
|
>>> len(db.connection.queries)
|
||||||
|
9
|
||||||
|
|
||||||
|
# With select_related():
|
||||||
|
>>> db.reset_queries()
|
||||||
|
>>> world = Species.objects.all().select_related()
|
||||||
|
>>> [o.genus.family for o in world]
|
||||||
|
[<Family: Drosophilidae>, <Family: Hominidae>, <Family: Fabaceae>, <Family: Amanitacae>]
|
||||||
|
>>> len(db.connection.queries)
|
||||||
|
1
|
||||||
|
|
||||||
|
# The "depth" argument to select_related() will stop the descent at a particular level:
|
||||||
|
>>> db.reset_queries()
|
||||||
|
>>> pea = Species.objects.select_related(depth=1).get(name="sativum")
|
||||||
|
>>> pea.genus.family.order.klass.phylum.kingdom.domain
|
||||||
|
<Domain: Eukaryota>
|
||||||
|
|
||||||
|
# Notice: one few query than above because of depth=1
|
||||||
|
>>> len(db.connection.queries)
|
||||||
|
7
|
||||||
|
|
||||||
|
>>> db.reset_queries()
|
||||||
|
>>> pea = Species.objects.select_related(depth=5).get(name="sativum")
|
||||||
|
>>> pea.genus.family.order.klass.phylum.kingdom.domain
|
||||||
|
<Domain: Eukaryota>
|
||||||
|
>>> len(db.connection.queries)
|
||||||
|
3
|
||||||
|
|
||||||
|
>>> db.reset_queries()
|
||||||
|
>>> world = Species.objects.all().select_related(depth=2)
|
||||||
|
>>> [o.genus.family.order for o in world]
|
||||||
|
[<Order: Diptera>, <Order: Primates>, <Order: Fabales>, <Order: Agaricales>]
|
||||||
|
>>> len(db.connection.queries)
|
||||||
|
5
|
||||||
|
|
||||||
|
# Reset DEBUG to where we found it.
|
||||||
|
>>> settings.DEBUG = False
|
||||||
|
"""}
|
@ -32,4 +32,11 @@ class Bug639Test(unittest.TestCase):
|
|||||||
p = manip.save(qd)
|
p = manip.save(qd)
|
||||||
|
|
||||||
# Check the savecount stored on the object (see the model)
|
# Check the savecount stored on the object (see the model)
|
||||||
self.assertEqual(p._savecount, 1)
|
self.assertEqual(p._savecount, 1)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""
|
||||||
|
Make sure to delete the "uploaded" file to avoid clogging /tmp.
|
||||||
|
"""
|
||||||
|
p = Photo.objects.get()
|
||||||
|
os.unlink(p.get_image_filename())
|
@ -17,6 +17,8 @@ r"""
|
|||||||
'07'
|
'07'
|
||||||
>>> format(my_birthday, 'M')
|
>>> format(my_birthday, 'M')
|
||||||
'Jul'
|
'Jul'
|
||||||
|
>>> format(my_birthday, 'b')
|
||||||
|
'jul'
|
||||||
>>> format(my_birthday, 'n')
|
>>> format(my_birthday, 'n')
|
||||||
'7'
|
'7'
|
||||||
>>> format(my_birthday, 'N')
|
>>> format(my_birthday, 'N')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user