1
0
mirror of https://github.com/django/django.git synced 2025-07-05 02:09:13 +00:00

i18n: merged r722:774 from trunk

git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@775 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Georg Bauer 2005-10-04 19:34:43 +00:00
parent 8c2b8aaee6
commit 6e2b74d65e
18 changed files with 182 additions and 37 deletions

View File

@ -18,10 +18,10 @@
#changelist {position:relative; width:100%;}
#changelist table {width:100%;}
.change-list .filtered table { border-right:1px solid #ddd; }
.change-list .filtered table { border-right:1px solid #ddd, width:100%; }
.change-list .filtered {min-height:400px; _height:400px;}
.change-list .filtered {background:white url(../img/admin/changelist-bg.gif) top right repeat-y !important;}
.change-list .filtered table, .filtered .paginator, .filtered #toolbar, .filtered div.xfull {margin-right:160px !important; width:auto !important; }
.change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {margin-right:160px !important; width:auto !important; }
.change-list .filtered table tbody th {padding-right:10px;}
#changelist .toplinks {border-bottom:1px solid #ccc !important;}
#changelist .paginator { color:#666; border-top:1px solid #eee; border-bottom:1px solid #eee; background:white url(../img/admin/nav-bg.gif) 0 180% repeat-x; overflow:hidden;}

View File

@ -120,7 +120,7 @@ IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', 'fav
SECRET_KEY = ''
# Path to the "jing" executable -- needed to validate XMLFields
JING_PATH = "/usr/bin/jng"
JING_PATH = "/usr/bin/jing"
##############
# MIDDLEWARE #

View File

@ -100,6 +100,9 @@ class ForNode(template.Node):
# shortcuts for current loop iteration number
'counter0': i,
'counter': i+1,
# reverse counter iteration numbers
'revcounter': len_values - i,
'revcounter0': len_values - i - 1,
# boolean values designating first and last times through loop
'first': (i == 0),
'last': (i == len_values - 1),
@ -471,6 +474,10 @@ def do_for(parser, token):
========================== ================================================
``forloop.counter`` The current iteration of the loop (1-indexed)
``forloop.counter0`` The current iteration of the loop (0-indexed)
``forloop.revcounter`` The number of iterations from the end of the
loop (1-indexed)
``forloop.revcounter0`` The number of iterations from the end of the
loop (0-indexed)
``forloop.first`` True if this is the first time through the loop
``forloop.last`` True if this is the last time through the loop
``forloop.parentloop`` For nested loops, this is the loop "above" the

View File

@ -156,18 +156,23 @@ get_sql_reset.args = APP_ARGS
def get_sql_initial_data(mod):
"Returns a list of the initial INSERT SQL statements for the given module."
from django.core import db
output = []
app_label = mod._MODELS[0]._meta.app_label
output.append(_get_packages_insert(app_label))
app_dir = os.path.normpath(os.path.join(os.path.dirname(mod.__file__), '../sql'))
for klass in mod._MODELS:
opts = klass._meta
# Add custom SQL, if it's available.
sql_file_name = os.path.join(app_dir, opts.module_name + '.sql')
if os.path.exists(sql_file_name):
fp = open(sql_file_name, 'r')
sql_files = [os.path.join(app_dir, opts.module_name + '.' + db.DATABASE_ENGINE + '.sql'),
os.path.join(app_dir, opts.module_name + '.sql')]
for sql_file in sql_files:
if os.path.exists(sql_file):
fp = open(sql_file)
output.append(fp.read())
fp.close()
# Content types.
output.append(_get_contenttype_insert(opts))
# Permissions.

View File

@ -7,7 +7,7 @@ from django.conf.settings import LANGUAGE_CODE, SETTINGS_MODULE
class FeedConfiguration:
def __init__(self, slug, title_cb, link_cb, description_cb, get_list_func_cb, get_list_kwargs,
param_func=None, param_kwargs_cb=None, get_list_kwargs_cb=None,
param_func=None, param_kwargs_cb=None, get_list_kwargs_cb=None, get_pubdate_cb=None,
enc_url=None, enc_length=None, enc_mime_type=None):
"""
slug -- Normal Python string. Used to register the feed.
@ -29,6 +29,9 @@ class FeedConfiguration:
get_list_kwargs_cb -- Function that takes the param and returns a
dictionary to use in addition to get_list_kwargs (if applicable).
get_pubdate_cb -- Function that takes the object and returns a datetime
to use as the publication date in the feed.
The three enc_* parameters are strings representing methods or
attributes to call on a particular item to get its enclosure
information. Each of those methods/attributes should return a normal
@ -41,6 +44,7 @@ class FeedConfiguration:
self.get_list_kwargs = get_list_kwargs
self.param_func, self.param_kwargs_cb = param_func, param_kwargs_cb
self.get_list_kwargs_cb = get_list_kwargs_cb
self.get_pubdate_cb = get_pubdate_cb
assert (None == enc_url == enc_length == enc_mime_type) or (enc_url is not None and enc_length is not None and enc_mime_type is not None)
self.enc_url = enc_url
self.enc_length = enc_length
@ -95,6 +99,7 @@ class FeedConfiguration:
description = description_template.render(Context({'obj': obj, 'site': current_site})).decode('utf-8'),
unique_id=link,
enclosure=enc,
pubdate = self.get_pubdate_cb and self.get_pubdate_cb(obj) or None,
)
return f

View File

@ -523,7 +523,7 @@ def _get_submit_row_template(opts, app_label, add, change, show_delete, ordered_
if not opts.admin.save_as or add:
t.append('{%% if not is_popup %%}<input type="submit" value="Save and add another" name="_addanother" %s/>{%% endif %%}' % \
(ordered_objects and change and 'onclick="submitOrderForm();"' or ''))
t.append('<input type="submit" value="Save and continue editing" name="_continue" %s/>' % \
t.append('{%% if not is_popup %%}<input type="submit" value="Save and continue editing" name="_continue" %s/>{%% endif %%}' % \
(ordered_objects and change and 'onclick="submitOrderForm();"' or ''))
t.append('<input type="submit" value="Save" class="default" %s/>' % \
(ordered_objects and change and 'onclick="submitOrderForm();"' or ''))

View File

@ -8,7 +8,8 @@ from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect
from django.core.exceptions import Http404, ObjectDoesNotExist, ImproperlyConfigured
def create_object(request, app_label, module_name, template_name=None,
extra_context={}, post_save_redirect=None, login_required=False):
template_loader=template_loader, extra_context={},
post_save_redirect=None, login_required=False):
"""
Generic object-creation function.
@ -65,8 +66,9 @@ def create_object(request, app_label, module_name, template_name=None,
return HttpResponse(t.render(c))
def update_object(request, app_label, module_name, object_id=None, slug=None,
slug_field=None, template_name=None, extra_lookup_kwargs={},
extra_context={}, post_save_redirect=None, login_required=False):
slug_field=None, template_name=None, template_loader=template_loader,
extra_lookup_kwargs={}, extra_context={}, post_save_redirect=None,
login_required=False):
"""
Generic object-update function.
@ -139,7 +141,8 @@ def update_object(request, app_label, module_name, object_id=None, slug=None,
def delete_object(request, app_label, module_name, post_delete_redirect,
object_id=None, slug=None, slug_field=None, template_name=None,
extra_lookup_kwargs={}, extra_context={}, login_required=False):
template_loader=template_loader, extra_lookup_kwargs={},
extra_context={}, login_required=False):
"""
Generic object-delete function.

View File

@ -7,7 +7,8 @@ from django.utils.httpwrappers import HttpResponse
import datetime, time
def archive_index(request, app_label, module_name, date_field, num_latest=15,
template_name=None, extra_lookup_kwargs={}, extra_context={}):
template_name=None, template_loader=template_loader,
extra_lookup_kwargs={}, extra_context={}):
"""
Generic top-level archive of date-based objects.
@ -49,7 +50,8 @@ def archive_index(request, app_label, module_name, date_field, num_latest=15,
return HttpResponse(t.render(c))
def archive_year(request, year, app_label, module_name, date_field,
template_name=None, extra_lookup_kwargs={}, extra_context={}):
template_name=None, template_loader=template_loader,
extra_lookup_kwargs={}, extra_context={}):
"""
Generic yearly archive view.
@ -85,8 +87,8 @@ def archive_year(request, year, app_label, module_name, date_field,
return HttpResponse(t.render(c))
def archive_month(request, year, month, app_label, module_name, date_field,
month_format='%b', template_name=None, extra_lookup_kwargs={},
extra_context={}):
month_format='%b', template_name=None, template_loader=template_loader,
extra_lookup_kwargs={}, extra_context={}):
"""
Generic monthly archive view.
@ -138,7 +140,8 @@ def archive_month(request, year, month, app_label, module_name, date_field,
def archive_day(request, year, month, day, app_label, module_name, date_field,
month_format='%b', day_format='%d', template_name=None,
extra_lookup_kwargs={}, extra_context={}, allow_empty=False):
template_loader=template_loader, extra_lookup_kwargs={},
extra_context={}, allow_empty=False):
"""
Generic daily archive view.
@ -201,7 +204,8 @@ def archive_today(request, **kwargs):
def object_detail(request, year, month, day, app_label, module_name, date_field,
month_format='%b', day_format='%d', object_id=None, slug=None,
slug_field=None, template_name=None, template_name_field=None,
extra_lookup_kwargs={}, extra_context={}):
template_loader=template_loader, extra_lookup_kwargs={},
extra_context={}):
"""
Generic detail view from year/month/day/slug or year/month/day/id structure.

View File

@ -7,7 +7,8 @@ from django.core.paginator import ObjectPaginator, InvalidPage
from django.core.exceptions import Http404, ObjectDoesNotExist
def object_list(request, app_label, module_name, paginate_by=None, allow_empty=False,
template_name=None, extra_lookup_kwargs={}, extra_context={}):
template_name=None, template_loader=template_loader,
extra_lookup_kwargs={}, extra_context={}):
"""
Generic list of objects.
@ -76,7 +77,8 @@ def object_list(request, app_label, module_name, paginate_by=None, allow_empty=F
def object_detail(request, app_label, module_name, object_id=None, slug=None,
slug_field=None, template_name=None, template_name_field=None,
extra_lookup_kwargs={}, extra_context={}):
template_loader=template_loader, extra_lookup_kwargs={},
extra_context={}):
"""
Generic list of objects.

View File

@ -524,7 +524,7 @@ model with an ``ImageField`` will also get this method.
get_FOO_url()
-------------
For every ``FileField``, the object will have a ``get_FOO_filename()`` method,
For every ``FileField``, the object will have a ``get_FOO_url()`` method,
where ``FOO`` is the name of the field. This returns the full URL to the file,
according to your ``MEDIA_URL`` setting. If the value is blank, this method
returns an empty string.

View File

@ -249,6 +249,27 @@ Here are all available field types:
The admin represents this as an ``<input type="file">`` (a file-upload widget).
Using a `FieldField` or an ``ImageField`` (see below) in a model takes a few
steps:
1. In your settings file, you'll need to define ``MEDIA_ROOT``as the
full path to a directory where you'd like Django to store uploaded
files. (For performance, these files are not stored in the database.)
Define ``MEDIA_URL`` as the base public URL of that directory. Make
sure that this directory is writable by the Web server's user
account.
2. Add the ``FileField`` or ``ImageField`` to your model, making sure
to define the ``upload_to`` option to tell Django to which
subdirectory of ``MEDIA_ROOT`` it should upload files.
3. All that will be stored in your database is a path to the file
(relative to ``MEDIA_ROOT``). You'll must likely want to use the
convenience ``get_<fieldname>_url`` function provided by Django. For
example, if your ``ImageField`` is called ``mug_shot``, you can get
the absolute URL to your image in a template with ``{{
object.get_mug_shot_url }}``.
.. _`strftime formatting`: http://docs.python.org/lib/module-time.html#l2h-1941
``FloatField``

View File

@ -29,8 +29,8 @@ Then edit your ``httpd.conf`` file and add the following::
PythonDebug On
</Location>
...and replace ``myproject.settings.main`` with the path to your settings file,
in dotted-package syntax.
...and replace ``myproject.settings.main`` with the Python path to your
settings file.
This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the
Django mod_python handler." It passes the value of ``DJANGO_SETTINGS_MODULE``

90
docs/outputting_pdf.txt Normal file
View File

@ -0,0 +1,90 @@
===========================
Outputting PDFs with Django
===========================
This document explains how to output PDF files dynamically using Django views.
This is made possible by the excellent, open-source ReportLab_ Python PDF
library.
The advantage of generating PDF files dynamically is that you can create
customized PDFs for different purposes -- say, for different users or different
pieces of content.
For example, Django was used at kusports.com to generate customized,
printer-friendly NCAA tournament brackets, as PDF files, for people
participating in a March Madness contest.
.. _ReportLab: http://www.reportlab.org/rl_toolkit.html
Install ReportLab
=================
Download and install the ReportLab library from http://www.reportlab.org/downloads.html.
The `user guide`_ (not coincidentally, a PDF file) explains how to install it.
Test your installation by importing it in the Python interactive interpreter::
>>> import reportlab
If that command doesn't raise any errors, the installation worked.
.. _user guide: http://www.reportlab.org/rsrc/userguide.pdf
Write your view
===============
The key to generating PDFs dynamically with Django is that the ReportLab API
acts on file-like objects, and Django's ``HttpResponse`` objects are file-like
objects.
.. admonition:: Note
For more information on ``HttpResponse`` objects, see
`Request and response objects`_.
.. _Request and response objects: http://www.djangoproject.com/documentation/request_response/
Here's a "Hello World" example::
from reportlab.pdfgen import canvas
from django.utils.httpwrappers import HttpResponse
def some_view(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
# Create the PDF object, using the response object as its "file."
p = canvas.Canvas(response)
# Draw things on the PDF. Here's where the PDF generation happens.
# See the ReportLab documentation for the full list of functionality.
p.drawString(100, 100, "Hello world.")
# Close the PDF object cleanly, and we're done.
p.showPage()
p.save()
return response
The code and comments should be self-explanatory, but a few things deserve a
mention:
* The response gets a special mimetype, ``application/pdf``. This tells
browsers that the document is a PDF file, rather than an HTML file. If
you leave this off, browsers will probably interpret the output as HTML,
which would result in ugly, scary gobbledygook in the browser window.
* The response gets an additional ``Content-Disposition`` header, which
contains the name of the PDF file. This filename is arbitrary: Call it
whatever you want. It'll be used by browsers in the "Save as..."
dialogue, etc.
* Hooking into the ReportLab API is easy: Just pass ``response`` as the
first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
file-like object, and ``HttpResponse`` objects fit the bill.
* Note that all subsequent PDF-generation methods are called on the PDF
object (in this case, ``p``) -- not on ``response``.
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
file.

View File

@ -376,6 +376,10 @@ Built-in tag reference
========================== ================================================
``forloop.counter`` The current iteration of the loop (1-indexed)
``forloop.counter0`` The current iteration of the loop (0-indexed)
``forloop.revcounter`` The number of iterations from the end of the
loop (1-indexed)
``forloop.revcounter0`` The number of iterations from the end of the
loop (0-indexed)
``forloop.first`` True if this is the first time through the loop
``forloop.last`` True if this is the last time through the loop
``forloop.parentloop`` For nested loops, this is the loop "above" the

View File

@ -267,7 +267,7 @@ every template automatic access to the current time, use something like this::
from django.core.template import Context
import datetime
class TimeContext(template.Context):
class TimeContext(Context):
def __init__(self, *args, **kwargs):
Context.__init__(self, *args, **kwargs)
self['current_time'] = datetime.datetime.now()

View File

@ -385,23 +385,23 @@ Let's jump back into the Python interactive shell::
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> polls.get_object(id__exact=1)
What's up
What's up?
>>> polls.get_object(question__startswith='What')
What's up
What's up?
>>> polls.get_object(pub_date__year=2005)
What's up
What's up?
>>> polls.get_object(id__exact=2)
Traceback (most recent call last):
...
PollDoesNotExist: Poll does not exist for {'id__exact': 2}
>>> polls.get_list(question__startswith='What')
[What's up]
[What's up?]
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to polls.get_object(id__exact=1).
>>> polls.get_object(pk=1)
What's up
What's up?
# Make sure our custom method worked.
>>> p = polls.get_object(pk=1)
@ -419,7 +419,7 @@ Let's jump back into the Python interactive shell::
# Choice objects have API access to their related Poll objects.
>>> c.get_poll()
What's up
What's up?
# And vice versa: Poll objects get access to Choice objects.
>>> p.get_choice_list()

View File

@ -91,8 +91,8 @@ Finally, it calls that ``detail()`` function like so::
detail(request=<HttpRequest object>, poll_id=23)
The ``poll_id=23`` part comes from ``(?P<poll_id>\d+)``. Using
``(?<name>pattern)`` "captures" the text matched by ``pattern`` and sends it as
a keyword argument to the view function.
``(?P<name>pattern)`` "captures" the text matched by ``pattern`` and sends it
as a keyword argument to the view function.
Because the URL patterns are regular expressions, there really is no limit on
what you can do with them. And there's no need to add URL cruft such as

View File

@ -108,6 +108,10 @@ TEMPLATE_TESTS = {
### FOR TAG ###############################################################
'for-tag01': ("{% for val in values %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "123"),
'for-tag02': ("{% for val in values reversed %}{{ val }}{% endfor %}", {"values": [1, 2, 3]}, "321"),
'for-tag-vars01': ("{% for val in values %}{{ forloop.counter }}{% endfor %}", {"values": [6, 6, 6]}, "123"),
'for-tag-vars02': ("{% for val in values %}{{ forloop.counter0 }}{% endfor %}", {"values": [6, 6, 6]}, "012"),
'for-tag-vars03': ("{% for val in values %}{{ forloop.revcounter }}{% endfor %}", {"values": [6, 6, 6]}, "321"),
'for-tag-vars04': ("{% for val in values %}{{ forloop.revcounter0 }}{% endfor %}", {"values": [6, 6, 6]}, "210"),
### IFEQUAL TAG ###########################################################
'ifequal01': ("{% ifequal a b %}yes{% endifequal %}", {"a": 1, "b": 2}, ""),