Permalink
Browse files

Merge branch 'master' of github.com:django-docs-ja/django-docs-ja

  • Loading branch information...
2 parents c5afdb5 + d5e9586 commit 9dfd414ff70c7e7847b324cd3dd52bac609d2bb2 @hdknr committed May 10, 2012
Showing with 319 additions and 224 deletions.
  1. +124 −145 _ext/djangodocs.py
  2. +135 −37 topics/forms/formsets.txt
  3. +60 −42 topics/forms/media.txt
View
269 _ext/djangodocs.py
@@ -2,23 +2,30 @@
"""
Sphinx plugins for Django documentation.
"""
+import os
+import re
-import docutils.nodes
-import docutils.transforms
-import sphinx
-import sphinx.addnodes
+from docutils import nodes, transforms
try:
- from sphinx import builders
+ import json
except ImportError:
- import sphinx.builder as builders
-import sphinx.directives
-import sphinx.environment
-try:
- import sphinx.writers.html as sphinx_htmlwriter
-except ImportError:
- import sphinx.htmlwriter as sphinx_htmlwriter
-import sphinx.roles
-from docutils import nodes
+ try:
+ import simplejson as json
+ except ImportError:
+ try:
+ from django.utils import simplejson as json
+ except ImportError:
+ json = None
+
+from sphinx import addnodes, roles, __version__ as sphinx_ver
+from sphinx.builders.html import StandaloneHTMLBuilder
+from sphinx.writers.html import SmartyPantsHTMLTranslator
+from sphinx.util.console import bold
+from sphinx.util.compat import Directive
+
+# RE for option descriptions without a '--' prefix
+simple_option_desc_re = re.compile(
+ r'([-_a-zA-Z0-9]+)(\s*.*?)(?=,\s+(?:/|-|--)|$)')
def setup(app):
app.add_crossref_type(
@@ -54,105 +61,90 @@ def setup(app):
parse_node = parse_django_adminopt_node,
)
app.add_config_value('django_next_version', '0.0', True)
- app.add_directive('versionadded', parse_version_directive, 1, (1, 1, 1))
- app.add_directive('versionchanged', parse_version_directive, 1, (1, 1, 1))
- app.add_transform(SuppressBlockquotes)
-
- # Monkeypatch PickleHTMLBuilder so that it doesn't die in Sphinx 0.4.2
- if sphinx.__version__ == '0.4.2':
- monkeypatch_pickle_builder()
-
-def parse_version_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- env = state.document.settings.env
- is_nextversion = env.config.django_next_version == arguments[0]
- ret = []
- node = sphinx.addnodes.versionmodified()
- ret.append(node)
- if not is_nextversion:
- if len(arguments) == 1:
- linktext = 'Please, see the release notes <releases-%s>' % (arguments[0])
- xrefs = sphinx.roles.xfileref_role('ref', linktext, linktext, lineno, state)
- node.extend(xrefs[0])
- node['version'] = arguments[0]
- else:
- node['version'] = "Development version"
- node['type'] = name
- if len(arguments) == 2:
- inodes, messages = state.inline_text(arguments[1], lineno+1)
- node.extend(inodes)
- if content:
- state.nested_parse(content, content_offset, node)
- ret = ret + messages
- env.note_versionchange(node['type'], node['version'], node, lineno)
- return ret
-
-
-class SuppressBlockquotes(docutils.transforms.Transform):
- """
- Remove the default blockquotes that encase indented list, tables, etc.
- """
- default_priority = 300
-
- suppress_blockquote_child_nodes = (
- docutils.nodes.bullet_list,
- docutils.nodes.enumerated_list,
- docutils.nodes.definition_list,
- docutils.nodes.literal_block,
- docutils.nodes.doctest_block,
- docutils.nodes.line_block,
- docutils.nodes.table
- )
-
- def apply(self):
- for node in self.document.traverse(docutils.nodes.block_quote):
- if len(node.children) == 1 and isinstance(node.children[0], self.suppress_blockquote_child_nodes):
- node.replace_self(node.children[0])
+ app.add_directive('versionadded', VersionDirective)
+ app.add_directive('versionchanged', VersionDirective)
+ app.add_builder(DjangoStandaloneHTMLBuilder)
+
+
+class VersionDirective(Directive):
+ has_content = True
+ required_arguments = 1
+ optional_arguments = 1
+ final_argument_whitespace = True
+ option_spec = {}
+
+ def run(self):
+ env = self.state.document.settings.env
+ arg0 = self.arguments[0]
+ is_nextversion = env.config.django_next_version == arg0
+ ret = []
+ node = addnodes.versionmodified()
+ ret.append(node)
+ if not is_nextversion:
+ if len(self.arguments) == 1:
+ linktext = u'リリースノートを参照してください </releases/%s>' % (arg0)
+ xrefs = roles.XRefRole()('doc', linktext, linktext, self.lineno, self.state)
+ node.extend(xrefs[0])
+ node['version'] = arg0
+ else:
+ node['version'] = "Development version"
+ node['type'] = self.name
+ if len(self.arguments) == 2:
+ inodes, messages = self.state.inline_text(self.arguments[1], self.lineno+1)
+ node.extend(inodes)
+ if self.content:
+ self.state.nested_parse(self.content, self.content_offset, node)
+ ret = ret + messages
+ env.note_versionchange(node['type'], node['version'], node, self.lineno)
+ return ret
-class DjangoHTMLTranslator(sphinx_htmlwriter.SmartyPantsHTMLTranslator):
+
+class DjangoHTMLTranslator(SmartyPantsHTMLTranslator):
"""
Django-specific reST to HTML tweaks.
"""
# Don't use border=1, which docutils does by default.
def visit_table(self, node):
+ self._table_row_index = 0 # Needed by Sphinx
self.body.append(self.starttag(node, 'table', CLASS='docutils'))
-
+
# <big>? Really?
def visit_desc_parameterlist(self, node):
self.body.append('(')
self.first_param = 1
-
+ self.param_separator = node.child_text_separator
+
def depart_desc_parameterlist(self, node):
self.body.append(')')
- pass
-
- #
- # Don't apply smartypants to literal blocks
- #
- def visit_literal_block(self, node):
- self.no_smarty += 1
- sphinx_htmlwriter.SmartyPantsHTMLTranslator.visit_literal_block(self, node)
-
- def depart_literal_block(self, node):
- sphinx_htmlwriter.SmartyPantsHTMLTranslator.depart_literal_block(self, node)
- self.no_smarty -= 1
-
+
+ if sphinx_ver < '1.0.8':
+ #
+ # Don't apply smartypants to literal blocks
+ #
+ def visit_literal_block(self, node):
+ self.no_smarty += 1
+ SmartyPantsHTMLTranslator.visit_literal_block(self, node)
+
+ def depart_literal_block(self, node):
+ SmartyPantsHTMLTranslator.depart_literal_block(self, node)
+ self.no_smarty -= 1
+
#
- # Turn the "new in version" stuff (versoinadded/versionchanged) into a
+ # Turn the "new in version" stuff (versionadded/versionchanged) into a
# better callout -- the Sphinx default is just a little span,
# which is a bit less obvious that I'd like.
#
- # FIXME: these messages are all hardcoded in English. We need to chanage
+ # FIXME: these messages are all hardcoded in English. We need to change
# that to accomodate other language docs, but I can't work out how to make
- # that work and I think it'll require Sphinx 0.5 anyway.
+ # that work.
#
version_text = {
'deprecated': u'Django %s で撤廃されました',
'versionchanged': u'Django %s で変更されました',
'versionadded': u'Django %s で新たに登場しました',
}
-
+
def visit_versionmodified(self, node):
self.body.append(
self.starttag(node, 'div', CLASS=node['type'])
@@ -162,41 +154,28 @@ def visit_versionmodified(self, node):
len(node) and ":" or "."
)
self.body.append('<span class="title">%s</span> ' % title)
-
+
def depart_versionmodified(self, node):
self.body.append("</div>\n")
-
+
# Give each section a unique ID -- nice for custom CSS hooks
- # This is different on docutils 0.5 vs. 0.4...
-
- if hasattr(sphinx_htmlwriter.SmartyPantsHTMLTranslator, 'start_tag_with_title') and sphinx.__version__ == '0.4.2':
- def start_tag_with_title(self, node, tagname, **atts):
- node = {
- 'classes': node.get('classes', []),
- 'ids': ['s-%s' % i for i in node.get('ids', [])]
- }
- return self.starttag(node, tagname, **atts)
-
- else:
- def visit_section(self, node):
- old_ids = node.get('ids', [])
- node['ids'] = ['s-' + i for i in old_ids]
- if sphinx.__version__ != '0.4.2':
- node['ids'].extend(old_ids)
- sphinx_htmlwriter.SmartyPantsHTMLTranslator.visit_section(self, node)
- node['ids'] = old_ids
+ def visit_section(self, node):
+ old_ids = node.get('ids', [])
+ node['ids'] = ['s-' + i for i in old_ids]
+ node['ids'].extend(old_ids)
+ SmartyPantsHTMLTranslator.visit_section(self, node)
+ node['ids'] = old_ids
def parse_django_admin_node(env, sig, signode):
command = sig.split(' ')[0]
env._django_curr_admin_command = command
title = "django-admin.py %s" % sig
- signode += sphinx.addnodes.desc_name(title, title)
+ signode += addnodes.desc_name(title, title)
return sig
def parse_django_adminopt_node(env, sig, signode):
"""A copy of sphinx.directives.CmdoptionDesc.parse_signature()"""
- from sphinx import addnodes
- from sphinx.directives.desc import option_desc_re
+ from sphinx.domains.std import option_desc_re
count = 0
firstname = ''
for m in option_desc_re.finditer(sig):
@@ -208,44 +187,44 @@ def parse_django_adminopt_node(env, sig, signode):
if not count:
firstname = optname
count += 1
+ if not count:
+ for m in simple_option_desc_re.finditer(sig):
+ optname, args = m.groups()
+ if count:
+ signode += addnodes.desc_addname(', ', ', ')
+ signode += addnodes.desc_name(optname, optname)
+ signode += addnodes.desc_addname(args, args)
+ if not count:
+ firstname = optname
+ count += 1
if not firstname:
raise ValueError
return firstname
-def monkeypatch_pickle_builder():
- import shutil
- from os import path
- try:
- import cPickle as pickle
- except ImportError:
- import pickle
- from sphinx.util.console import bold
-
- def handle_finish(self):
- # dump the global context
- outfilename = path.join(self.outdir, 'globalcontext.pickle')
- f = open(outfilename, 'wb')
- try:
- pickle.dump(self.globalcontext, f, 2)
- finally:
- f.close()
-
- self.info(bold('dumping search index...'))
- self.indexer.prune(self.env.all_docs)
- f = open(path.join(self.outdir, 'searchindex.pickle'), 'wb')
- try:
- self.indexer.dump(f, 'pickle')
- finally:
- f.close()
- # copy the environment file from the doctree dir to the output dir
- # as needed by the web app
- shutil.copyfile(path.join(self.doctreedir, builders.ENV_PICKLE_FILENAME),
- path.join(self.outdir, builders.ENV_PICKLE_FILENAME))
+class DjangoStandaloneHTMLBuilder(StandaloneHTMLBuilder):
+ """
+ Subclass to add some extra things we need.
+ """
- # touch 'last build' file, used by the web application to determine
- # when to reload its environment and clear the cache
- open(path.join(self.outdir, builders.LAST_BUILD_FILENAME), 'w').close()
+ name = 'djangohtml'
- builders.PickleHTMLBuilder.handle_finish = handle_finish
-
+ def finish(self):
+ super(DjangoStandaloneHTMLBuilder, self).finish()
+ if json is None:
+ self.warn("cannot create templatebuiltins.js due to missing simplejson dependency")
+ return
+ self.info(bold("writing templatebuiltins.js..."))
+ xrefs = self.env.domaindata["std"]["objects"]
+ templatebuiltins = {
+ "ttags": [n for ((t, n), (l, a)) in xrefs.items()
+ if t == "templatetag" and l == "ref/templates/builtins"],
+ "tfilters": [n for ((t, n), (l, a)) in xrefs.items()
+ if t == "templatefilter" and l == "ref/templates/builtins"],
+ }
+ outfilename = os.path.join(self.outdir, "templatebuiltins.js")
+ f = open(outfilename, 'wb')
+ f.write('var django_template_builtins = ')
+ json.dump(templatebuiltins, f)
+ f.write(';\n')
+ f.close();
View
172 topics/forms/formsets.txt
@@ -4,7 +4,7 @@
フォームセット (formsets)
=============================
-:revision-up-to: 11321 (1.1) unfinished
+:revision-up-to: 17812 (1.4)
フォームセットとは、同じページで複数のフォームを扱うための抽象化レイヤで、
いわばデータグリッドのようなものです。フォームセットを説明するために、まず
@@ -27,17 +27,40 @@
ぞれを普通のフォームとして表示する機能があります::
>>> formset = ArticleFormSet()
- >>> for form in formset.forms:
+ >>> for form in formset:
... print form.as_table()
<tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
<tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
-出力を見て分かる通り、フォームは一つだけ表示されています。これは、
+出力を見て分かる通り、空のフォームが一つだけ表示されています。
+今表示されている空っぽのフォームの合計は、 ``extra`` パラメータ
+によってコントロールされます。
``formset_factory`` のデフォルトの設定で、「追加のフォーム表示数 (extra)」
-を 1 に設定しているからです。表示数は ``extra`` パラメタで制御できます::
+を 1 に設定しているからです。二つの空っぽのフォームを出す例は::
>>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
+.. versionchanged:: 1.3
+
+Django 1.3 で重要視されるのは、 フォームセットのインスタンスがイテレート
+(iterate)できないということです。フォームセットの表示をするために、
+``forms`` アトリビュート(attribute)をイテレートします。::
+
+ >>> formset = ArticleFormSet()
+ >>> for form in formset.forms:
+ ... print form.as_table()
+
+``formset.forms`` をイテレートすることは、フォームが作成された順番で
+フォームを並べるのと同じことです。通常、フォームセットのイテレータは
+この順番でフォームを表示します、しかしこの順番を :meth:`__iter__()`
+メソッドを使って別の順番へと変更することができます。
+
+フォームセットは、インデックスを入れこむこともできます。フォームセットは
+組み込まれたフォームを返します。もし、 ``__iter__`` を上書きしたならば、
+``__getitem__`` も、フォームとのマッチングのために上書きする必要があります。
+
+.. _formsets-initial-data:
+
フォームセットに初期データを指定する
-------------------------------------
@@ -49,10 +72,10 @@
>>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
>>> formset = ArticleFormSet(initial=[
... {'title': u'Django is now open source',
- ... 'pub_date': datetime.date.today()},
+ ... 'pub_date': datetime.date.today(),}
... ])
- >>> for form in formset.forms:
+ >>> for form in formset:
... print form.as_table()
<tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Django is now open source" id="id_form-0-title" /></td></tr>
<tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-12" id="id_form-0-pub_date" /></td></tr>
@@ -69,6 +92,8 @@
:ref:`Creating formsets from models with model formsets <model-formsets>`.
+.. _formsets-max-num:
+
フォームの最大表示数を制限する
------------------------------------
@@ -77,13 +102,20 @@
>>> ArticleFormSet = formset_factory(ArticleForm, extra=2, max_num=1)
>>> formset = ArticleFormset()
- >>> for form in formset.forms:
+ >>> for form in formset:
... print form.as_table()
<tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
<tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
-``max_num`` のデフォルト値は表示数に制限がないことを示す ``0`` に設定されて
-います。
+.. versionchanged:: 1.2
+
+もし、 ``max_num`` の値が存在するオブジェクトの合計より大きい場合、
+``extra`` 次第で、空のフォームがフォームセットに加えられます。
+フォームの合計の長さは ``max_num`` を超えることはできません。
+
+``max_num`` の値が ``None`` (通常です)であった場合、表示されるフォームの数には
+制限がありません。 ``max_num`` の値が ``0`` から ``None`` になったことを
+覚えておいてください。 version 1.2 から ``0`` は有効な値となりました。
フォームセットのバリデーション
------------------------------------
@@ -93,7 +125,12 @@
簡単に検証できます::
>>> ArticleFormSet = formset_factory(ArticleForm)
- >>> formset = ArticleFormSet({})
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'1',
+ ... 'form-INITIAL_FORMS': u'0',
+ ... 'form-MAX_NUM_FORMS': u'',
+ ... }
+ >>> formset = ArticleFormSet(data)
>>> formset.is_valid()
True
@@ -105,8 +142,9 @@
>>> data = {
... 'form-TOTAL_FORMS': u'2',
... 'form-INITIAL_FORMS': u'0',
+ ... 'form-MAX_NUM_FORMS': u'',
... 'form-0-title': u'Test',
- ... 'form-0-pub_date': u'16 June 1904',
+ ... 'form-0-pub_date': u'1904-06-16',
... 'form-1-title': u'Test',
... 'form-1-pub_date': u'', # <-- this date is missing but required
... }
@@ -116,16 +154,33 @@
>>> formset.errors
[{}, {'pub_date': [u'This field is required.']}]
-As we can see, ``formset.errors`` is a list whose entries correspond to the
-forms in the formset. Validation was performed for each of the two forms, and
-the expected error message appears for the second item.
+確認できるように、 ``formset.errors`` はリストで、
+そのエントリーは、フォームセットの中のフォームのものです。
+バリデーションは、二つのフォームそれぞれに働いて、
+リストの二つ目のアイテムにエラーメッセージが表示されています。
+
+また、初めのデータと入力されたデータが異なっているかどうかも
+チェックできます。(すなわち、フォームは何のデータもなしに送信されない)
+ということです。
+
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'1',
+ ... 'form-INITIAL_FORMS': u'0',
+ ... 'form-MAX_NUM_FORMS': u'',
+ ... 'form-0-title': u'',
+ ... 'form-0-pub_date': u'',
+ ... }
+ >>> formset = ArticleFormSet(data)
+ >>> formset.has_changed()
+ False
.. _understanding-the-managementform:
``ManagementForm`` を理解する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-上の例でフォームセットに与えた初期値には、追加のデータが入っていたことに気
+上の例でフォームセットに与えた初期値には、追加のデータ( ``form-TOTAL_FORMS``
+, ``form-INITIAL_FORMS`` , ``form-MAX_NUM_FORMS`` )が入っていたことに気
付いたでしょうか。これはフォームセットで内部的に処理されているフォーム、
``ManagementForm`` で扱うためのデータです。追加のデータ抜きでフォームセット
を使おうとすると、例外が送出されます::
@@ -143,19 +198,32 @@ the expected error message appears for the second item.
めに使われます。 JavaScript でフォームを動的に追加する場合、
``ManagementForm`` データのカウントも増やさねばなりません。
-.. versionadded:: 1.1
+マネジメントフォームはフォームセット自身のアトリビュートとして使用可能です。
+テンプレートにフォームセットをレンダリングする際、
+``{{ my_formset.management_form }}`` をレンダリングすることでマネジメント
+データを含むことができます。(フォームセットのところは適切な名前に変えて
+使ってください)
+
+``total_form_count`` と ``initial_form_count``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-``total_form_count`` and ``initial_form_count``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``BaseFormSet`` は二つの ``ManagementForm`` に類似したメソッドを持っています、
+``total_form_count`` と ``initial_form_count`` です。
-``BaseModelFormSet`` has a couple of methods that are closely related to the
-``ManagementForm``, ``total_form_count`` and ``initial_form_count``.
+``total_form_count`` は、フォームセットの中のフォームの合計の数を返します。
+``initial_form_count`` はフォームセットの中のフォームのうち、データが
+入力されているものだけを返します、また幾つのフォームが必要かを判断するのに
+使えます。おそらくこれらのメソッドを上書きする必要に迫られることはないでしょ
+う。まずは、実行する前に何を実行するのかを理解しておいたほうがよいでしょう。
-``total_form_count`` returns the total number of forms in this formset.
-``initial_form_count`` returns the number of forms in the formset that were
-pre-filled, and is also used to determine how many forms are required. You
-will probably never need to override either of these methods, so please be
-sure you understand what they do before doing so.
+.. versionadded:: 1.2
+
+``empty_form``
+~~~~~~~~~~~~~~
+
+``BaseFormSet`` は ``empty_form`` という追加のアトリビュートを提供します。
+これは、 JavaScript を使った動的なフォーム生成を簡単にするために
+``__prefix__`` のプレフィクスをフォームインスタンスとともに返します。
カスタムのフォームセットバリデーション
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -176,17 +244,18 @@ sure you understand what they do before doing so.
... form = self.forms[i]
... title = form.cleaned_data['title']
... if title in titles:
- ... raise forms.ValidationError, "Articles in a set must have distinct titles."
+ ... raise forms.ValidationError("Articles in a set musthave distinct titles.")
... titles.append(title)
>>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
>>> data = {
... 'form-TOTAL_FORMS': u'2',
... 'form-INITIAL_FORMS': u'0',
+ ... 'form-MAX_NUM_FORMS': u'',
... 'form-0-title': u'Test',
- ... 'form-0-pub_date': u'16 June 1904',
+ ... 'form-0-pub_date': u'1904-06-16',
... 'form-1-title': u'Test',
- ... 'form-1-pub_date': u'23 June 1912',
+ ... 'form-1-pub_date': u'1912-06-23',
... }
>>> formset = ArticleFormSet(data)
>>> formset.is_valid()
@@ -214,14 +283,14 @@ sure you understand what they do before doing so.
デフォルト値: ``False``
-Lets create a formset with the ability to order::
+並べ替え機能とともに、フォームセットを作ってみましょう::
>>> ArticleFormSet = formset_factory(ArticleForm, can_order=True)
>>> formset = ArticleFormSet(initial=[
... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
... ])
- >>> for form in formset.forms:
+ >>> for form in formset:
... print form.as_table()
<tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
<tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
@@ -269,16 +338,18 @@ Lets create a formset with the ability to order::
デフォルト値: ``False``
-Lets create a formset with the ability to delete::
+削除機能とともに、フォームセットを作ってみましょう::
>>> ArticleFormSet = formset_factory(ArticleForm, can_delete=True)
>>> formset = ArticleFormSet(initial=[
... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
... ])
- >>> for form in formset.forms:
+ >>> for form in formset:
.... print form.as_table()
- <input type="hidden" name="form-TOTAL_FORMS" value="3" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="2" id="id_form-INITIAL_FORMS" />
+ <input type="hidden" name="form-TOTAL_FORMS" value="3" id="id_form-TOTAL_FORMS" />
+ <input type="hidden" name="form-INITIAL_FORMS" value="2" id="id_form-INITIAL_FORMS" />
+ <input type="hidden" name="form-MAX_NUM_FORMS" id="id_form-MAX_NUM_FORMS" />
<tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
<tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
<tr><th><label for="id_form-0-DELETE">Delete:</label></th><td><input type="checkbox" name="form-0-DELETE" id="id_form-0-DELETE" /></td></tr>
@@ -297,6 +368,7 @@ Lets create a formset with the ability to delete::
>>> data = {
... 'form-TOTAL_FORMS': u'3',
... 'form-INITIAL_FORMS': u'2',
+ ... 'form-MAX_NUM_FORMS': u'',
... 'form-0-title': u'Article #1',
... 'form-0-pub_date': u'2008-05-10',
... 'form-0-DELETE': u'on',
@@ -330,7 +402,7 @@ Lets create a formset with the ability to delete::
>>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
>>> formset = ArticleFormSet()
- >>> for form in formset.forms:
+ >>> for form in formset:
... print form.as_table()
<tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
<tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
@@ -359,10 +431,10 @@ Lets create a formset with the ability to delete::
.. code-block:: html+django
- <form method="POST" action="">
+ <form method="post" action="">
{{ formset.management_form }}
<table>
- {% for form in formset.forms %}
+ {% for form in formset %}
{{ form }}
{% endfor %}
</table>
@@ -373,7 +445,7 @@ Lets create a formset with the ability to delete::
.. code-block:: html+django
- <form method="POST" action="">
+ <form method="post" action="">
<table>
{{ formset }}
</table>
@@ -382,6 +454,32 @@ Lets create a formset with the ability to delete::
このショートカットは、フォームセットの ``as_table`` を呼び出した時と同じ内
容を出力します。
+.. _manually-rendered-can-delete-and-can-order:
+
+``can_delete`` と ``can_order`` を手動で出力する。
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+もし、テンプレートの中で手動でフィールドを出力するなら、
+``can_delete`` パラメータは ``{{ form.DELETE }}`` で出力できます:
+
+.. code-block:: html+django
+
+ <form method="post" action="">
+ {{ formset.management_form }}
+ {% for form in formset %}
+ {{ form.id }}
+ <ul>
+ <li>{{ form.title }}</li>
+ {% if formset.can_delete %}
+ <li>{{ form.DELETE }}</li>
+ {% endif %}
+ </ul>
+ {% endfor %}
+ </form>
+
+同じように、もしフォームセットが並べ替え機能を所持するなら( ``can_order=True``
+)、これもまた ``{{ form.ORDER }}`` で呼び出すことができます。
+
複数のフォームセットを一つのビュー内で使う
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
View
102 topics/forms/media.txt
@@ -1,9 +1,9 @@
.. _topics-forms-media:
-Form Media
-==========
+フォームメディア( Form Media )
+==============================
-:revision-up-to: 11321 (1.1) unfinished
+:revision-up-to: 17812 (1.4)
魅力的で使いやすい Web フォームをレンダしたいなら、 HTML だけでは能力不足で
しょう。CSS スタイルシートが必要でしょうし、ファンシーな "Web2.0" 的ウィジェッ
@@ -132,12 +132,12 @@ CSS ファイルのリストを指定してください。以下の例では、
んなメディアファイル要件を宣言したかに関係なく行われます。例えば、上の例の
カレンダーウィジェットを、以下のように拡張したとします::
- class FancyCalendarWidget(CalendarWidget):
- class Media:
- css = {
- 'all': ('fancy.css',)
- }
- js = ('whizbang.js',)
+ >>> class FancyCalendarWidget(CalendarWidget):
+ ... class Media:
+ ... css = {
+ ... 'all': ('fancy.css',)
+ ... }
+ ... js = ('whizbang.js',)
>>> w = FancyCalendarWidget()
>>> print w.media
@@ -194,32 +194,52 @@ CSS ファイルのリストを指定してください。以下の例では、
動的なメディアプロパティの戻り値を構築するための詳しい方法は、
`Media オブジェクト`_ の節を参照してください。
+.. _form-media-paths:
+
.. _ref-forms-paths-in-media-definitions:
メディア定義のパス
--------------------
+.. versionchanged:: 1.3
+
メディアファイルの場所を指定するためのパスは、相対でも絶対でもかまいません。
パスが ``'/'``, ``'http://'``, ``'https://'`` のいずれかで開始していれば、
-絶対パス指定として、値をそのまま使います。それ以外のパスの前には
-``settings.MEDIA_URL`` の値を付加します。例えば、 ``MEDIA_URL`` が
-``http://media.example.com/`` の場合は、以下のウィジェット::
+絶対パス指定として、値をそのまま使います。それ以外のパスの前には適切な
+プレフィクス(prefix)を指定します。
+:doc:`staticfiles app </ref/contrib/staticfiles> の部分的な紹介として、
+"静的なファイル"(イメージや CSS, JavaScript, など)に完全な Web ページを
+表示するための二つの新しい設定が追加されました。:
+:setting:`STATIC_URL` and :setting:`STATIC_ROOT` がそれです。
+適切なプレフィクスを使うために、 Django は :setting:`STATIC_URL` が
+``None`` ではないかどうかを確かめ、 :setting:`MEDIA_URL` を使うために自動的に
+巻き戻ります。例えば、もしサイトの :setting:`MEDIA_URL` が
+``'http://uploads.example.com/'`` であって :setting:`STATIC_URL` が ``None``
+であった場合::
+
+ >>> class CalenderWidget(forms.TextInput):
+ class Media:
+ css = {
+ 'all: ('/css/pretty.css',),
+ }
+ js = ('animations.js', 'http://othersite.com/actions.js')
- class CalendarWidget(forms.TextInput):
- class Media:
- css = {
- 'all': ('/css/pretty.css',),
- }
- js = ('animations.js', 'http://othersite.com/actions.js')
+ >>> w = CalendarWidget()
+ >>> print w.media
+ <link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://uploads.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://othersite.com/actions.js"></script>
-は、以下のように HTML を出力します::
+ですが、もし :setting:`STATIC_URL` が ``'http://static.example.com/'`` なら
+ば::
>>> w = CalendarWidget()
>>> print w.media
<link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
- <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://othersite.com/actions.js"></script>
+
``Media`` オブジェクト
------------------------
@@ -255,17 +275,16 @@ HTML コードです。
``Media`` オブジェクトは加算できます。二つの ``Media`` オブジェクトを加算す
ると、結果の ``Media`` オブジェクトには両方のメディアファイル情報が入ります::
- class CalendarWidget(forms.TextInput):
- class Media:
- css = {
- 'all': ('pretty.css',)
- }
- js = ('animations.js', 'actions.js')
-
- class OtherWidget(forms.TextInput):
- class Media:
- js = ('whizbang.js',)
+ >>> class CalendarWidget(forms.TextInput):
+ ... class Media:
+ ... css = {
+ ... 'all': ('pretty.css',)
+ ... }
+ ... js = ('animations.js', 'actions.js')
+ >>> class OtherWidget(forms.TextInput):
+ ... class Media:
+ ... js = ('whizbang.js',)
>>> w1 = CalendarWidget()
>>> w2 = OtherWidget()
>>> print w1.media + w2.media
@@ -287,9 +306,9 @@ HTML コードです。
フォームを構成する全てのウィジェットのメディアファイル定義を加算したもので
す::
- class ContactForm(forms.Form):
- date = DateField(widget=CalendarWidget)
- name = CharField(max_length=40, widget=OtherWidget)
+ >>> class ContactForm(forms.Form):
+ ... date = DateField(widget=CalendarWidget)
+ ... name = CharField(max_length=40, widget=OtherWidget)
>>> f = ContactForm()
>>> f.media
@@ -301,15 +320,14 @@ HTML コードです。
フォーム固有のメディア宣言を付加したい場合、例えば、フォームのレイアウトを
決める CSS を指定したい場合には、以下のようにメディア定義を追加します::
- class ContactForm(forms.Form):
- date = DateField(widget=CalendarWidget)
- name = CharField(max_length=40, widget=OtherWidget)
-
- class Media:
- css = {
- 'all': ('layout.css',)
- }
-
+ >>> class ContactForm(forms.Form):
+ ... date = DateField(widget=CalendarWidget)
+ ... name = CharField(max_length=40, widget=OtherWidget)
+ ...
+ ... class Media:
+ ... css = {
+ ... 'all': ('layout.css',)
+ ... }
>>> f = ContactForm()
>>> f.media
<link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />

0 comments on commit 9dfd414

Please sign in to comment.