Merge remote-tracking branch 'django/master' into t3011
This commit is contained in:
commit
579f152e4a
|
@ -191,7 +191,8 @@ class GeoModelTest(TestCase):
|
||||||
cities1 = City.objects.all()
|
cities1 = City.objects.all()
|
||||||
# Only PostGIS would support a 'select *' query because of its recognized
|
# Only PostGIS would support a 'select *' query because of its recognized
|
||||||
# HEXEWKB format for geometry fields
|
# HEXEWKB format for geometry fields
|
||||||
cities2 = City.objects.raw('select id, name, asText(point) from geoapp_city')
|
as_text = 'ST_AsText' if postgis else 'asText'
|
||||||
|
cities2 = City.objects.raw('select id, name, %s(point) from geoapp_city' % as_text)
|
||||||
self.assertEqual(len(cities1), len(list(cities2)))
|
self.assertEqual(len(cities1), len(list(cities2)))
|
||||||
self.assertTrue(isinstance(cities2[0].point, Point))
|
self.assertTrue(isinstance(cities2[0].point, Point))
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,14 @@ The ``ContentTypeManager``
|
||||||
probably won't ever need to call this method yourself; Django will call
|
probably won't ever need to call this method yourself; Django will call
|
||||||
it automatically when it's needed.
|
it automatically when it's needed.
|
||||||
|
|
||||||
|
.. method:: get_for_id(id)
|
||||||
|
|
||||||
|
Lookup a :class:`~django.contrib.contenttypes.models.ContentType` by ID.
|
||||||
|
Since this method uses the same shared cache as
|
||||||
|
:meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model`,
|
||||||
|
it's preferred to use this method over the usual
|
||||||
|
``ContentType.objects.get(pk=id)``
|
||||||
|
|
||||||
.. method:: get_for_model(model[, for_concrete_model=True])
|
.. method:: get_for_model(model[, for_concrete_model=True])
|
||||||
|
|
||||||
Takes either a model class or an instance of a model, and returns the
|
Takes either a model class or an instance of a model, and returns the
|
||||||
|
|
|
@ -155,7 +155,8 @@ or the
|
||||||
:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names()`
|
:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names()`
|
||||||
method, which are documented in the
|
method, which are documented in the
|
||||||
:class:`~django.views.generic.base.TemplateResponseMixin` documentation. The
|
:class:`~django.views.generic.base.TemplateResponseMixin` documentation. The
|
||||||
latter one allows you to use a different template for each form.
|
latter one allows you to use a different template for each form (:ref:`see the
|
||||||
|
example below <wizard-template-for-each-form>`).
|
||||||
|
|
||||||
This template expects a ``wizard`` object that has various items attached to
|
This template expects a ``wizard`` object that has various items attached to
|
||||||
it:
|
it:
|
||||||
|
@ -238,6 +239,65 @@ wizard's :meth:`as_view` method takes a list of your
|
||||||
(r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2])),
|
(r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2])),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
.. _wizard-template-for-each-form:
|
||||||
|
|
||||||
|
Using a different template for each form
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
As mentioned above, you may specify a different template for each form.
|
||||||
|
Consider an example using a form wizard to implement a multi-step checkout
|
||||||
|
process for an online store. In the first step, the user specifies a billing
|
||||||
|
and shipping address. In the second step, the user chooses payment type. If
|
||||||
|
they chose to pay by credit card, they will enter credit card information in
|
||||||
|
the next step. In the final step, they will confirm the purchase.
|
||||||
|
|
||||||
|
Here's what the view code might look like::
|
||||||
|
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.contrib.formtools.wizard.views import SessionWizardView
|
||||||
|
|
||||||
|
FORMS = [("address", myapp.forms.AddressForm),
|
||||||
|
("paytype", myapp.forms.PaymentChoiceForm),
|
||||||
|
("cc", myapp.forms.CreditCardForm),
|
||||||
|
("confirmation", myapp.forms.OrderForm)]
|
||||||
|
|
||||||
|
TEMPLATES = {"address": "checkout/billingaddress.html",
|
||||||
|
"paytype": "checkout/paymentmethod.html",
|
||||||
|
"cc": "checkout/creditcard.html",
|
||||||
|
"confirmation": "checkout/confirmation.html"}
|
||||||
|
|
||||||
|
def pay_by_credit_card(wizard):
|
||||||
|
"""Return true if user opts to pay by credit card"""
|
||||||
|
# Get cleaned data from payment step
|
||||||
|
cleaned_data = wizard.get_cleaned_data_for_step('paytype') or {'method': 'none'}
|
||||||
|
# Return true if the user selected credit card
|
||||||
|
return cleaned_data['method'] == 'cc'
|
||||||
|
|
||||||
|
|
||||||
|
class OrderWizard(SessionWizardView):
|
||||||
|
def get_template_names(self):
|
||||||
|
return [TEMPLATES[self.steps.current]]
|
||||||
|
|
||||||
|
def done(self, form_list, **kwargs):
|
||||||
|
do_something_with_the_form_data(form_list)
|
||||||
|
return HttpResponseRedirect('/page-to-redirect-to-when-done/')
|
||||||
|
...
|
||||||
|
|
||||||
|
The ``urls.py`` file would contain something like::
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
(r'^checkout/$', OrderWizard.as_view(FORMS, condition_dict={'cc': pay_by_credit_card})),
|
||||||
|
)
|
||||||
|
|
||||||
|
Note that the ``OrderWizard`` object is initialized with a list of pairs.
|
||||||
|
The first element in the pair is a string that corresponds to the name of the
|
||||||
|
step and the second is the form class.
|
||||||
|
|
||||||
|
In this example, the
|
||||||
|
:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names()`
|
||||||
|
method returns a list containing a single template, which is selected based on
|
||||||
|
the name of the current step.
|
||||||
|
|
||||||
.. _wizardview-advanced-methods:
|
.. _wizardview-advanced-methods:
|
||||||
|
|
||||||
Advanced ``WizardView`` methods
|
Advanced ``WizardView`` methods
|
||||||
|
|
|
@ -674,8 +674,8 @@ __ http://spatialreference.org/ref/epsg/32140/
|
||||||
.. admonition:: Raw queries
|
.. admonition:: Raw queries
|
||||||
|
|
||||||
When using :doc:`raw queries </topics/db/sql>`, you should generally wrap
|
When using :doc:`raw queries </topics/db/sql>`, you should generally wrap
|
||||||
your geometry fields with the ``asText()`` SQL function so as the field
|
your geometry fields with the ``asText()`` SQL function (or ``ST_AsText``
|
||||||
value will be recognized by GEOS::
|
for PostGIS) so as the field value will be recognized by GEOS::
|
||||||
|
|
||||||
City.objects.raw('SELECT id, name, asText(point) from myapp_city')
|
City.objects.raw('SELECT id, name, asText(point) from myapp_city')
|
||||||
|
|
||||||
|
|
|
@ -852,7 +852,7 @@ Slightly complex built-in ``Field`` classes
|
||||||
``MultiValueField``
|
``MultiValueField``
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. class:: MultiValueField(**kwargs)
|
.. class:: MultiValueField(fields=(), **kwargs)
|
||||||
|
|
||||||
* Default widget: ``TextInput``
|
* Default widget: ``TextInput``
|
||||||
* Empty value: ``''`` (an empty string)
|
* Empty value: ``''`` (an empty string)
|
||||||
|
@ -861,22 +861,39 @@ Slightly complex built-in ``Field`` classes
|
||||||
as an argument to the ``MultiValueField``.
|
as an argument to the ``MultiValueField``.
|
||||||
* Error message keys: ``required``, ``invalid``
|
* Error message keys: ``required``, ``invalid``
|
||||||
|
|
||||||
This abstract field (must be subclassed) aggregates the logic of multiple
|
Aggregates the logic of multiple fields that together produce a single
|
||||||
fields. Subclasses should not have to implement clean(). Instead, they must
|
value.
|
||||||
implement compress(), which takes a list of valid values and returns a
|
|
||||||
"compressed" version of those values -- a single value. For example,
|
This field is abstract and must be subclassed. In contrast with the
|
||||||
:class:`SplitDateTimeField` is a subclass which combines a time field and
|
single-value fields, subclasses of :class:`MultiValueField` must not
|
||||||
a date field into a datetime object.
|
implement :meth:`~django.forms.Field.clean` but instead - implement
|
||||||
|
:meth:`~MultiValueField.compress`.
|
||||||
|
|
||||||
Takes one extra required argument:
|
Takes one extra required argument:
|
||||||
|
|
||||||
.. attribute:: fields
|
.. attribute:: fields
|
||||||
|
|
||||||
A list of fields which are cleaned into a single field. Each value in
|
A tuple of fields whose values are cleaned and subsequently combined
|
||||||
``clean`` is cleaned by the corresponding field in ``fields`` -- the first
|
into a single value. Each value of the field is cleaned by the
|
||||||
value is cleaned by the first field, the second value is cleaned by
|
corresponding field in ``fields`` -- the first value is cleaned by the
|
||||||
the second field, etc. Once all fields are cleaned, the list of clean
|
first field, the second value is cleaned by the second field, etc.
|
||||||
values is "compressed" into a single value.
|
Once all fields are cleaned, the list of clean values is combined into
|
||||||
|
a single value by :meth:`~MultiValueField.compress`.
|
||||||
|
|
||||||
|
.. attribute:: MultiValueField.widget
|
||||||
|
|
||||||
|
Must be a subclass of :class:`django.forms.MultiWidget`.
|
||||||
|
Default value is :class:`~django.forms.widgets.TextInput`, which
|
||||||
|
probably is not very useful in this case.
|
||||||
|
|
||||||
|
.. method:: compress(data_list)
|
||||||
|
|
||||||
|
Takes a list of valid values and returns a "compressed" version of
|
||||||
|
those values -- in a single value. For example,
|
||||||
|
:class:`SplitDateTimeField` is a subclass which combines a time field
|
||||||
|
and a date field into a ``datetime`` object.
|
||||||
|
|
||||||
|
This method must be implemented in the subclasses.
|
||||||
|
|
||||||
``SplitDateTimeField``
|
``SplitDateTimeField``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -11,6 +11,16 @@ A widget is Django's representation of a HTML input element. The widget
|
||||||
handles the rendering of the HTML, and the extraction of data from a GET/POST
|
handles the rendering of the HTML, and the extraction of data from a GET/POST
|
||||||
dictionary that corresponds to the widget.
|
dictionary that corresponds to the widget.
|
||||||
|
|
||||||
|
.. tip::
|
||||||
|
|
||||||
|
Widgets should not be confused with the :doc:`form fields </ref/forms/fields>`.
|
||||||
|
Form fields deal with the logic of input validation and are used directly
|
||||||
|
in templates. Widgets deal with rendering of HTML form input elements on
|
||||||
|
the web page and extraction of raw submitted data. However, widgets do
|
||||||
|
need to be :ref:`assigned <widget-to-field>` to form fields.
|
||||||
|
|
||||||
|
.. _widget-to-field:
|
||||||
|
|
||||||
Specifying widgets
|
Specifying widgets
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -95,15 +105,23 @@ choices are inherent to the model and not just the representational widget.
|
||||||
Customizing widget instances
|
Customizing widget instances
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
When Django renders a widget as HTML, it only renders the bare minimum
|
When Django renders a widget as HTML, it only renders very minimal markup -
|
||||||
HTML - Django doesn't add a class definition, or any other widget-specific
|
Django doesn't add class names, or any other widget-specific attributes. This
|
||||||
attributes. This means that all :class:`TextInput` widgets will appear the same
|
means, for example, that all :class:`TextInput` widgets will appear the same
|
||||||
on your Web page.
|
on your Web pages.
|
||||||
|
|
||||||
If you want to make one widget look different to another, you need to
|
There are two ways to customize widgets: :ref:`per widget instance
|
||||||
specify additional attributes for each widget. When you specify a
|
<styling-widget-instances>` and :ref:`per widget class <styling-widget-classes>`.
|
||||||
widget, you can provide a list of attributes that will be added to the
|
|
||||||
rendered HTML for the widget.
|
.. _styling-widget-instances:
|
||||||
|
|
||||||
|
Styling widget instances
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If you want to make one widget instance look different from another, you will
|
||||||
|
need to specify additional attributes at the time when the widget object is
|
||||||
|
instantiated and assigned to a form field (and perhaps add some rules to your
|
||||||
|
CSS files).
|
||||||
|
|
||||||
For example, take the following simple form::
|
For example, take the following simple form::
|
||||||
|
|
||||||
|
@ -128,9 +146,7 @@ On a real Web page, you probably don't want every widget to look the same. You
|
||||||
might want a larger input element for the comment, and you might want the
|
might want a larger input element for the comment, and you might want the
|
||||||
'name' widget to have some special CSS class. It is also possible to specify
|
'name' widget to have some special CSS class. It is also possible to specify
|
||||||
the 'type' attribute to take advantage of the new HTML5 input types. To do
|
the 'type' attribute to take advantage of the new HTML5 input types. To do
|
||||||
this, you use the :attr:`Widget.attrs` argument when creating the widget:
|
this, you use the :attr:`Widget.attrs` argument when creating the widget::
|
||||||
|
|
||||||
For example::
|
|
||||||
|
|
||||||
class CommentForm(forms.Form):
|
class CommentForm(forms.Form):
|
||||||
name = forms.CharField(
|
name = forms.CharField(
|
||||||
|
@ -147,24 +163,41 @@ Django will then include the extra attributes in the rendered output:
|
||||||
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
|
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
|
||||||
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
|
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
|
||||||
|
|
||||||
.. _built-in widgets:
|
.. _styling-widget-classes:
|
||||||
|
|
||||||
Built-in widgets
|
Styling widget classes
|
||||||
----------------
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Django provides a representation of all the basic HTML widgets, plus some
|
With widgets, it is possible to add media (``css`` and ``javascript``)
|
||||||
commonly used groups of widgets:
|
and more deeply customize their appearance and behavior.
|
||||||
|
|
||||||
``Widget``
|
In a nutshell, you will need to subclass the widget and either
|
||||||
~~~~~~~~~~
|
:ref:`define a class "Media" <media-as-a-static-definition>` as a member of the
|
||||||
|
subclass, or :ref:`create a property "media" <dynamic-property>`, returning an
|
||||||
|
instance of that class.
|
||||||
|
|
||||||
.. class:: Widget
|
These methods involve somewhat advanced Python programming and are described in
|
||||||
|
detail in the :doc:`Form Media </topics/forms/media>` topic guide.
|
||||||
|
|
||||||
This abstract class cannot be rendered, but provides the basic attribute :attr:`~Widget.attrs`.
|
.. _base-widget-classes:
|
||||||
|
|
||||||
|
Base Widget classes
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Base widget classes :class:`Widget` and :class:`MultiWidget` are subclassed by
|
||||||
|
all the :ref:`built-in widgets <built-in widgets>` and may serve as a
|
||||||
|
foundation for custom widgets.
|
||||||
|
|
||||||
|
.. class:: Widget(attrs=None)
|
||||||
|
|
||||||
|
This abstract class cannot be rendered, but provides the basic attribute
|
||||||
|
:attr:`~Widget.attrs`. You may also implement or override the
|
||||||
|
:meth:`~Widget.render()` method on custom widgets.
|
||||||
|
|
||||||
.. attribute:: Widget.attrs
|
.. attribute:: Widget.attrs
|
||||||
|
|
||||||
A dictionary containing HTML attributes to be set on the rendered widget.
|
A dictionary containing HTML attributes to be set on the rendered
|
||||||
|
widget.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
@ -172,6 +205,74 @@ commonly used groups of widgets:
|
||||||
>>> name.render('name', 'A name')
|
>>> name.render('name', 'A name')
|
||||||
u'<input title="Your name" type="text" name="name" value="A name" size="10" />'
|
u'<input title="Your name" type="text" name="name" value="A name" size="10" />'
|
||||||
|
|
||||||
|
.. method:: render(name, value, attrs=None)
|
||||||
|
|
||||||
|
Returns HTML for the widget, as a Unicode string. This method must be
|
||||||
|
implemented by the subclass, otherwise ``NotImplementedError`` will be
|
||||||
|
raised.
|
||||||
|
|
||||||
|
The 'value' given is not guaranteed to be valid input, therefore
|
||||||
|
subclass implementations should program defensively.
|
||||||
|
|
||||||
|
.. class:: MultiWidget(widgets, attrs=None)
|
||||||
|
|
||||||
|
A widget that is composed of multiple widgets.
|
||||||
|
:class:`~django.forms.widgets.MultiWidget` works hand in hand with the
|
||||||
|
:class:`~django.forms.MultiValueField`.
|
||||||
|
|
||||||
|
.. method:: render(name, value, attrs=None)
|
||||||
|
|
||||||
|
Argument `value` is handled differently in this method from the
|
||||||
|
subclasses of :class:`~Widget`.
|
||||||
|
|
||||||
|
If `value` is a list, output of :meth:`~MultiWidget.render` will be a
|
||||||
|
concatenation of rendered child widgets. If `value` is not a list, it
|
||||||
|
will be first processed by the method :meth:`~MultiWidget.decompress()`
|
||||||
|
to create the list and then processed as above.
|
||||||
|
|
||||||
|
Unlike in the single value widgets, method :meth:`~MultiWidget.render`
|
||||||
|
need not be implemented in the subclasses.
|
||||||
|
|
||||||
|
.. method:: decompress(value)
|
||||||
|
|
||||||
|
Returns a list of "decompressed" values for the given value of the
|
||||||
|
multi-value field that makes use of the widget. The input value can be
|
||||||
|
assumed as valid, but not necessarily non-empty.
|
||||||
|
|
||||||
|
This method **must be implemented** by the subclass, and since the
|
||||||
|
value may be empty, the implementation must be defensive.
|
||||||
|
|
||||||
|
The rationale behind "decompression" is that it is necessary to "split"
|
||||||
|
the combined value of the form field into the values of the individual
|
||||||
|
field encapsulated within the multi-value field (e.g. when displaying
|
||||||
|
the partially or fully filled-out form).
|
||||||
|
|
||||||
|
.. tip::
|
||||||
|
|
||||||
|
Note that :class:`~django.forms.MultiValueField` has a
|
||||||
|
complementary method :meth:`~django.forms.MultiValueField.compress`
|
||||||
|
with the opposite responsibility - to combine cleaned values of
|
||||||
|
all member fields into one.
|
||||||
|
|
||||||
|
|
||||||
|
.. _built-in widgets:
|
||||||
|
|
||||||
|
Built-in widgets
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Django provides a representation of all the basic HTML widgets, plus some
|
||||||
|
commonly used groups of widgets in the ``django.forms.widgets`` module,
|
||||||
|
including :ref:`the input of text <text-widgets>`, :ref:`various checkboxes
|
||||||
|
and selectors <selector-widgets>`, :ref:`uploading files <file-upload-widgets>`,
|
||||||
|
and :ref:`handling of multi-valued input <composite-widgets>`.
|
||||||
|
|
||||||
|
.. _text-widgets:
|
||||||
|
|
||||||
|
Widgets handling input of text
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
These widgets make use of the HTML elements ``input`` and ``textarea``.
|
||||||
|
|
||||||
``TextInput``
|
``TextInput``
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -205,39 +306,8 @@ commonly used groups of widgets:
|
||||||
|
|
||||||
Hidden input: ``<input type='hidden' ...>``
|
Hidden input: ``<input type='hidden' ...>``
|
||||||
|
|
||||||
``MultipleHiddenInput``
|
Note that there also is a :class:`MultipleHiddenInput` widget that
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
encapsulates a set of hidden input elements.
|
||||||
|
|
||||||
.. class:: MultipleHiddenInput
|
|
||||||
|
|
||||||
Multiple ``<input type='hidden' ...>`` widgets.
|
|
||||||
|
|
||||||
A widget that handles multiple hidden widgets for fields that have a list
|
|
||||||
of values.
|
|
||||||
|
|
||||||
.. attribute:: MultipleHiddenInput.choices
|
|
||||||
|
|
||||||
This attribute is optional when the field does not have a
|
|
||||||
:attr:`~Field.choices` attribute. If it does, it will override anything
|
|
||||||
you set here when the attribute is updated on the :class:`Field`.
|
|
||||||
|
|
||||||
``FileInput``
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. class:: FileInput
|
|
||||||
|
|
||||||
File upload input: ``<input type='file' ...>``
|
|
||||||
|
|
||||||
``ClearableFileInput``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. class:: ClearableFileInput
|
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
|
||||||
|
|
||||||
File upload input: ``<input type='file' ...>``, with an additional checkbox
|
|
||||||
input to clear the field's value, if the field is not required and has
|
|
||||||
initial data.
|
|
||||||
|
|
||||||
``DateInput``
|
``DateInput``
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
@ -297,6 +367,11 @@ commonly used groups of widgets:
|
||||||
|
|
||||||
Text area: ``<textarea>...</textarea>``
|
Text area: ``<textarea>...</textarea>``
|
||||||
|
|
||||||
|
.. _selector-widgets:
|
||||||
|
|
||||||
|
Selector and checkbox widgets
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
``CheckboxInput``
|
``CheckboxInput``
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -440,6 +515,50 @@ commonly used groups of widgets:
|
||||||
...
|
...
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
.. _file-upload-widgets:
|
||||||
|
|
||||||
|
File upload widgets
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
``FileInput``
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. class:: FileInput
|
||||||
|
|
||||||
|
File upload input: ``<input type='file' ...>``
|
||||||
|
|
||||||
|
``ClearableFileInput``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. class:: ClearableFileInput
|
||||||
|
|
||||||
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
File upload input: ``<input type='file' ...>``, with an additional checkbox
|
||||||
|
input to clear the field's value, if the field is not required and has
|
||||||
|
initial data.
|
||||||
|
|
||||||
|
.. _composite-widgets:
|
||||||
|
|
||||||
|
Composite widgets
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
``MultipleHiddenInput``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. class:: MultipleHiddenInput
|
||||||
|
|
||||||
|
Multiple ``<input type='hidden' ...>`` widgets.
|
||||||
|
|
||||||
|
A widget that handles multiple hidden widgets for fields that have a list
|
||||||
|
of values.
|
||||||
|
|
||||||
|
.. attribute:: MultipleHiddenInput.choices
|
||||||
|
|
||||||
|
This attribute is optional when the field does not have a
|
||||||
|
:attr:`~Field.choices` attribute. If it does, it will override anything
|
||||||
|
you set here when the attribute is updated on the :class:`Field`.
|
||||||
|
|
||||||
``MultiWidget``
|
``MultiWidget``
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -1338,9 +1338,6 @@ Default: ``'/accounts/logout/'``
|
||||||
|
|
||||||
LOGIN_URL counterpart.
|
LOGIN_URL counterpart.
|
||||||
|
|
||||||
.. note::
|
|
||||||
See the `note on LOGIN_REDIRECT_URL setting`_
|
|
||||||
|
|
||||||
.. setting:: MANAGERS
|
.. setting:: MANAGERS
|
||||||
|
|
||||||
MANAGERS
|
MANAGERS
|
||||||
|
|
|
@ -660,6 +660,36 @@ the handler, if ``created`` is ``True``, create the associated user profile::
|
||||||
.. seealso:: :doc:`/topics/signals` for more information on Django's signal
|
.. seealso:: :doc:`/topics/signals` for more information on Django's signal
|
||||||
dispatcher.
|
dispatcher.
|
||||||
|
|
||||||
|
Adding UserProfile fields to the admin
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
To add the UserProfile fields to the user page in the admin, define an
|
||||||
|
:class:`~django.contrib.admin.InlineModelAdmin` (for this example, we'll use a
|
||||||
|
:class:`~django.contrib.admin.StackedInline`) in your app's ``admin.py`` and
|
||||||
|
add it to a ``UserAdmin`` class which is registered with the
|
||||||
|
:class:`~django.contrib.auth.models.User` class::
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.admin import UserAdmin
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from my_user_profile_app.models import UserProfile
|
||||||
|
|
||||||
|
# Define an inline admin descriptor for UserProfile model
|
||||||
|
# which acts a bit like a singleton
|
||||||
|
class UserProfileInline(admin.StackedInline):
|
||||||
|
model = UserProfile
|
||||||
|
can_delete = False
|
||||||
|
verbose_name_plural = 'profile'
|
||||||
|
|
||||||
|
# Define a new User admin
|
||||||
|
class UserAdmin(UserAdmin):
|
||||||
|
inlines = (UserProfileInline, )
|
||||||
|
|
||||||
|
# Re-register UserAdmin
|
||||||
|
admin.site.unregister(User)
|
||||||
|
admin.site.register(User, UserAdmin)
|
||||||
|
|
||||||
Authentication in Web requests
|
Authentication in Web requests
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ in a form suitable for easy inclusion on your Web page.
|
||||||
whichever toolkit suits your requirements. Django is able to integrate
|
whichever toolkit suits your requirements. Django is able to integrate
|
||||||
with any JavaScript toolkit.
|
with any JavaScript toolkit.
|
||||||
|
|
||||||
|
.. _media-as-a-static-definition:
|
||||||
|
|
||||||
Media as a static definition
|
Media as a static definition
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
@ -78,10 +80,8 @@ A dictionary describing the CSS files required for various forms of output
|
||||||
media.
|
media.
|
||||||
|
|
||||||
The values in the dictionary should be a tuple/list of file names. See
|
The values in the dictionary should be a tuple/list of file names. See
|
||||||
`the section on media paths`_ for details of how to specify paths to media
|
:ref:`the section on media paths <form-media-paths>` for details of how to
|
||||||
files.
|
specify paths to media files.
|
||||||
|
|
||||||
.. _the section on media paths: `Paths in media definitions`_
|
|
||||||
|
|
||||||
The keys in the dictionary are the output media types. These are the same
|
The keys in the dictionary are the output media types. These are the same
|
||||||
types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
|
types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
|
||||||
|
@ -117,8 +117,8 @@ If this last CSS definition were to be rendered, it would become the following H
|
||||||
``js``
|
``js``
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
A tuple describing the required JavaScript files. See
|
A tuple describing the required JavaScript files. See :ref:`the section on
|
||||||
`the section on media paths`_ for details of how to specify paths to media
|
media paths <form-media-paths>` for details of how to specify paths to media
|
||||||
files.
|
files.
|
||||||
|
|
||||||
``extend``
|
``extend``
|
||||||
|
@ -164,10 +164,10 @@ declaration to the media declaration::
|
||||||
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
|
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
|
||||||
|
|
||||||
If you require even more control over media inheritance, define your media
|
If you require even more control over media inheritance, define your media
|
||||||
using a `dynamic property`_. Dynamic properties give you complete control over
|
using a :ref:`dynamic property <dynamic-property>`. Dynamic properties give
|
||||||
which media files are inherited, and which are not.
|
you complete control over which media files are inherited, and which are not.
|
||||||
|
|
||||||
.. _dynamic property: `Media as a dynamic property`_
|
.. _dynamic-property:
|
||||||
|
|
||||||
Media as a dynamic property
|
Media as a dynamic property
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@ -198,9 +198,9 @@ Paths in media definitions
|
||||||
.. versionchanged:: 1.3
|
.. versionchanged:: 1.3
|
||||||
|
|
||||||
Paths used to specify media can be either relative or absolute. If a path
|
Paths used to specify media can be either relative or absolute. If a path
|
||||||
starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
|
starts with ``/``, ``http://`` or ``https://``, it will be interpreted as an
|
||||||
path, and left as-is. All other paths will be prepended with the value of
|
absolute path, and left as-is. All other paths will be prepended with the value
|
||||||
the appropriate prefix.
|
of the appropriate prefix.
|
||||||
|
|
||||||
As part of the introduction of the
|
As part of the introduction of the
|
||||||
:doc:`staticfiles app </ref/contrib/staticfiles>` two new settings were added
|
:doc:`staticfiles app </ref/contrib/staticfiles>` two new settings were added
|
||||||
|
|
Loading…
Reference in New Issue