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()
|
||||
# Only PostGIS would support a 'select *' query because of its recognized
|
||||
# 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.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
|
||||
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])
|
||||
|
||||
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()`
|
||||
method, which are documented in 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
|
||||
it:
|
||||
|
@ -238,6 +239,65 @@ wizard's :meth:`as_view` method takes a list of your
|
|||
(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:
|
||||
|
||||
Advanced ``WizardView`` methods
|
||||
|
|
|
@ -674,8 +674,8 @@ __ http://spatialreference.org/ref/epsg/32140/
|
|||
.. admonition:: Raw queries
|
||||
|
||||
When using :doc:`raw queries </topics/db/sql>`, you should generally wrap
|
||||
your geometry fields with the ``asText()`` SQL function so as the field
|
||||
value will be recognized by GEOS::
|
||||
your geometry fields with the ``asText()`` SQL function (or ``ST_AsText``
|
||||
for PostGIS) so as the field value will be recognized by GEOS::
|
||||
|
||||
City.objects.raw('SELECT id, name, asText(point) from myapp_city')
|
||||
|
||||
|
|
|
@ -852,7 +852,7 @@ Slightly complex built-in ``Field`` classes
|
|||
``MultiValueField``
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. class:: MultiValueField(**kwargs)
|
||||
.. class:: MultiValueField(fields=(), **kwargs)
|
||||
|
||||
* Default widget: ``TextInput``
|
||||
* Empty value: ``''`` (an empty string)
|
||||
|
@ -861,22 +861,39 @@ Slightly complex built-in ``Field`` classes
|
|||
as an argument to the ``MultiValueField``.
|
||||
* Error message keys: ``required``, ``invalid``
|
||||
|
||||
This abstract field (must be subclassed) aggregates the logic of multiple
|
||||
fields. Subclasses should not have to implement clean(). Instead, they must
|
||||
implement compress(), which takes a list of valid values and returns a
|
||||
"compressed" version of those values -- a single value. For example,
|
||||
:class:`SplitDateTimeField` is a subclass which combines a time field and
|
||||
a date field into a datetime object.
|
||||
Aggregates the logic of multiple fields that together produce a single
|
||||
value.
|
||||
|
||||
This field is abstract and must be subclassed. In contrast with the
|
||||
single-value fields, subclasses of :class:`MultiValueField` must not
|
||||
implement :meth:`~django.forms.Field.clean` but instead - implement
|
||||
:meth:`~MultiValueField.compress`.
|
||||
|
||||
Takes one extra required argument:
|
||||
|
||||
.. attribute:: fields
|
||||
|
||||
A list of fields which are cleaned into a single field. Each value in
|
||||
``clean`` is cleaned by the corresponding field in ``fields`` -- the first
|
||||
value is cleaned by the first field, the second value is cleaned by
|
||||
the second field, etc. Once all fields are cleaned, the list of clean
|
||||
values is "compressed" into a single value.
|
||||
A tuple of fields whose values are cleaned and subsequently combined
|
||||
into a single value. Each value of the field is cleaned by the
|
||||
corresponding field in ``fields`` -- the first value is cleaned by the
|
||||
first field, the second value is cleaned by the second field, etc.
|
||||
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``
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -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
|
||||
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
|
||||
------------------
|
||||
|
||||
|
@ -95,15 +105,23 @@ choices are inherent to the model and not just the representational widget.
|
|||
Customizing widget instances
|
||||
----------------------------
|
||||
|
||||
When Django renders a widget as HTML, it only renders the bare minimum
|
||||
HTML - Django doesn't add a class definition, or any other widget-specific
|
||||
attributes. This means that all :class:`TextInput` widgets will appear the same
|
||||
on your Web page.
|
||||
When Django renders a widget as HTML, it only renders very minimal markup -
|
||||
Django doesn't add class names, or any other widget-specific attributes. This
|
||||
means, for example, that all :class:`TextInput` widgets will appear the same
|
||||
on your Web pages.
|
||||
|
||||
If you want to make one widget look different to another, you need to
|
||||
specify additional attributes for each widget. When you specify a
|
||||
widget, you can provide a list of attributes that will be added to the
|
||||
rendered HTML for the widget.
|
||||
There are two ways to customize widgets: :ref:`per widget instance
|
||||
<styling-widget-instances>` and :ref:`per widget class <styling-widget-classes>`.
|
||||
|
||||
.. _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::
|
||||
|
||||
|
@ -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
|
||||
'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
|
||||
this, you use the :attr:`Widget.attrs` argument when creating the widget:
|
||||
|
||||
For example::
|
||||
this, you use the :attr:`Widget.attrs` argument when creating the widget::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
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>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
|
||||
commonly used groups of widgets:
|
||||
With widgets, it is possible to add media (``css`` and ``javascript``)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
@ -172,6 +205,74 @@ commonly used groups of widgets:
|
|||
>>> name.render('name', 'A name')
|
||||
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``
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
@ -205,39 +306,8 @@ commonly used groups of widgets:
|
|||
|
||||
Hidden input: ``<input type='hidden' ...>``
|
||||
|
||||
``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`.
|
||||
|
||||
``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.
|
||||
Note that there also is a :class:`MultipleHiddenInput` widget that
|
||||
encapsulates a set of hidden input elements.
|
||||
|
||||
``DateInput``
|
||||
~~~~~~~~~~~~~
|
||||
|
@ -297,6 +367,11 @@ commonly used groups of widgets:
|
|||
|
||||
Text area: ``<textarea>...</textarea>``
|
||||
|
||||
.. _selector-widgets:
|
||||
|
||||
Selector and checkbox widgets
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``CheckboxInput``
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -440,6 +515,50 @@ commonly used groups of widgets:
|
|||
...
|
||||
</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``
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -1338,9 +1338,6 @@ Default: ``'/accounts/logout/'``
|
|||
|
||||
LOGIN_URL counterpart.
|
||||
|
||||
.. note::
|
||||
See the `note on LOGIN_REDIRECT_URL setting`_
|
||||
|
||||
.. setting:: 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
|
||||
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
|
||||
==============================
|
||||
|
||||
|
|
|
@ -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
|
||||
with any JavaScript toolkit.
|
||||
|
||||
.. _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.
|
||||
|
||||
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
|
||||
files.
|
||||
|
||||
.. _the section on media paths: `Paths in media definitions`_
|
||||
:ref:`the section on media paths <form-media-paths>` for details of how to
|
||||
specify paths to media files.
|
||||
|
||||
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',
|
||||
|
@ -117,8 +117,8 @@ If this last CSS definition were to be rendered, it would become the following H
|
|||
``js``
|
||||
~~~~~~
|
||||
|
||||
A tuple describing the required JavaScript files. See
|
||||
`the section on media paths`_ for details of how to specify paths to media
|
||||
A tuple describing the required JavaScript files. See :ref:`the section on
|
||||
media paths <form-media-paths>` for details of how to specify paths to media
|
||||
files.
|
||||
|
||||
``extend``
|
||||
|
@ -164,10 +164,10 @@ declaration to the media declaration::
|
|||
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
|
||||
|
||||
If you require even more control over media inheritance, define your media
|
||||
using a `dynamic property`_. Dynamic properties give you complete control over
|
||||
which media files are inherited, and which are not.
|
||||
using a :ref:`dynamic property <dynamic-property>`. Dynamic properties give
|
||||
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
|
||||
---------------------------
|
||||
|
@ -198,9 +198,9 @@ Paths in media definitions
|
|||
.. versionchanged:: 1.3
|
||||
|
||||
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
|
||||
path, and left as-is. All other paths will be prepended with the value of
|
||||
the appropriate prefix.
|
||||
starts with ``/``, ``http://`` or ``https://``, it will be interpreted as an
|
||||
absolute path, and left as-is. All other paths will be prepended with the value
|
||||
of the appropriate prefix.
|
||||
|
||||
As part of the introduction of the
|
||||
:doc:`staticfiles app </ref/contrib/staticfiles>` two new settings were added
|
||||
|
|
Loading…
Reference in New Issue