Skip to content

Commit

Permalink
Added 1 to 2 upgrade documentation [ci skip]
Browse files Browse the repository at this point in the history
  • Loading branch information
jpic committed Dec 17, 2013
1 parent 1b6b4b9 commit ebfb01a
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 10 deletions.
14 changes: 7 additions & 7 deletions README
Expand Up @@ -42,14 +42,14 @@ easier to work with and supports python3.
In this case, please refer to the `v2 documentation
<http://django-autocomplete-light.readthedocs.org/en/v2/>`_.

**To upgrade to v2**, just inherit from `autocomplete_light.ModelForm`. It
does everything like creating form fields (which didn't exist in v1) handling
generic relations, etc, etc .. And remove any reference to things that don't
exist anymore in your code (`get_widgets_dict()`, `FixedModelForm`, etc ...).
**To upgrade to v2**, please enjoy the `v1 to v2 upgrade instructions
<http://django-autocomplete-light.readthedocs.org/en/v2/1to2.html>`_ (documented with love !).

**If you're coming from v1**, you just need to read the documentation about the
`new design of forms
<http://django-autocomplete-light.readthedocs.org/en/v2/form.html#design-documentation>`_.
- the Autocomplete class design hasn't changed at all.
- ``yourlabsWidget()`` doesn't parses ``data-*`` options the same,
- the django/form python code has been re-organised ie.
``get_widgets_dict()`` is gone and ``autocomplete_light.ModelForm``
wraps around all features.

Resources
---------
Expand Down
200 changes: 200 additions & 0 deletions docs/source/1to2.rst
@@ -0,0 +1,200 @@
Upgrading from django-autocomplete-light v1 to v2
=================================================

You should not use widget directly anymore
------------------------------------------

We used to have things like this:

.. code-block:: python
class YourForm(autocomplete_light.GenericModelForm):
user = forms.ModelChoiceField(User.objects.all(),
widget=autocomplete_light.ChoiceWidget('UserAutocomplete'))
related = GenericModelChoiceField(
widget=autocomplete_light.ChoiceWidget(
autocomplete='AutocompleteTaggableItems',
autocomplete_js_attributes={'minimum_characters': 0}))
class Meta:
model = YourModel
This caused several problems:

- broke a DRY principle: if you have defined a ``user`` foreign key
**and** registered an Autocomplete for the model in question,
``User``, then you should not have to repeat this.
- broke the DRY principle since you had to set choices on both the
ModelChoiceField and the Autocomplete - ``UserAutocomplete`` in this
example.
- also, validation was done in the widget's ``render()`` function,
mostly for security reasons. Validation is not done in the widget
anymore, instead it is done in :py:mod:`autocomplete_light.fields`.

What should the above code be like ? Well it depends, it could just be:

.. code-block:: python
class YourForm(autocomplete_light.ModelForm):
class Meta:
model = YourModel
If you have registered an Autocomplete for the model that the ``user``
ForeignKey is for, then :py:class:`autocomplete_light.ModelForm
<autocomplete_light.forms.ModelForm>` will pick it up
automatically.

Assuming you have registered a generic autocomplete,
:py:class:`autocomplete_light.ModelForm
<autocomplete_light.forms.ModelForm>` will pick it up automatically.

If you want django's default behaviour back (``<select>``) then you could tell
:py:class:`autocomplete_light.ModelForm
<autocomplete_light.forms.ModelForm>` to not be "autocomplete-aware" for ``user`` as
such:

.. code-block:: python
class YourForm(autocomplete_light.ModelForm):
class Meta:
model = YourModel
autocomplete_exclude = ('user',)
You can still override the field using
:py:cls:`autocomplete_light.ModelChoiceField
<autocomplete_light.fields.ModelChoiceField>``
and
:py:cls:`autocomplete_light.GenericChoiceField
<autocomplete_light.fields.GenericChoiceField>``:

.. code-block:: python
class YourForm(autocomplete_light.ModelForm):
user = autocomplete_light.ModelChoiceField('UserAutocomplete')
related = autocomplete_light.GenericModelChoiceField('AutocompleteTaggableItems')
class Meta:
model = YourModel
autocomplete_exclude = ('user',)
You can still override widgets the same way as before though, but you should
consider the :ref:`dry-break`_ implications (which have nothing to do with
django-autocomplete-light actually, just an in-depth explanation of Django
design).

Python class re-organisation
----------------------------

Form classes like ``FixedModelform`` or ``GenericModelForm`` were
renamed. But if you can, just inherit from
:py:class:`autocomplete_light.ModelForm
<autocomplete_light.forms.ModelForm>` instead.

Generic field classes were moved from
``autocomplete_light.contrib.generic_m2m`` into
``autocomplete_light.fields``: just import
``autocomplete_light.GenericModelChoiceField`` and
``autocomplete_light.GenericModelMultipleChoiceField``.

Deprecation of ``autocomplete_js_attributes`` and ``widget_js_attributes``
--------------------------------------------------------------------------

In the past, we used ``autocomplete_js_attributes`` and
``widget_js_attributes``. Those are deprecated and HTML ``data``
attributes should be set directly instead.

For example:

.. code-block:: python
class PersonAutocomplete(autocomplete_light.AutocompleteModelBase):
model = Person
autocomplete_js_attributes = {
'minimum_characters': 0,
'placeholder': 'foo',
}
widget_js_attributes = {'max_values': 3}
Should now be:

.. code-block:: python
class PersonAutocomplete(autocomplete_light.AutocompleteModelBase):
model = Person
input_attrs = {
'data-autcomplete-minimum-characters': 0,
'placeholder': 'foo',
}
widget_attrs = {'data-widget-maximum-values': 3}
As you probably understand already magic inside
``autocomplete_js_attributes`` and ``widget_js_attributes`` is gone,
we're just setting plain simple HTML attributes now.

Also not the other two differences which are detailed below:

- ``max-values`` was renamed to ``maximum-values`` (see below),
- ``data-autocomplete-placeholder`` is gone in favor of HTML5 ``placeholder`` attribute (see below),

``max-values`` was renamed to ``maximum-values``
------------------------------------------------

For consistency with my one of my naming standards which is: no
abbreviations.

``data-autocomplete-placeholder`` is gone in favor of HTML5 ``placeholder`` attribute
-------------------------------------------------------------------------------------

It made no sense keeping ``data-autocomplete-placeholder`` since we now
have HTML5 ``placeholder`` attribute.

Widget template changes
-----------------------

This is a side effect from the deprecation of
``autocomplete_js_attributes`` and ``widget_js_attributes``.

This:

.. code-block:: django
<span class="autocomplete-light-widget {{ name }}
{% if widget.widget_js_attributes.max_values == 1 %}single{% else %}multiple{% endif %}"
id="{{ widget.html_id }}-wrapper"
{{ widget.widget_js_attributes|autocomplete_light_data_attributes }}
{{ widget.autocomplete_js_attributes|autocomplete_light_data_attributes:'autocomplete-' }}
>
Is now:

.. code-block:: django
<span id="{{ widget.html_id }}-wrapper" {{ widget_attrs }} >
Script changes
--------------

``.yourlabsWidget()`` used to parse ``data-*`` attributes:

- ``data-foo-bar`` used to set js attribute ``yourlabs.Widget.fooBar,
- ``data-autocomplete-foo-bar`` used to set js attribute ``yourlabs.Widget.autocomplete.fooBar``.

Now:

- ``.yourlabsWidget()`` parses ``data-widget-*`` attributes and,
- ``.yourlabsAutocomplete()`` parses ``data-autocomplete-*`` **on the ``<input />``** !

So this:

.. code-block:: html

<span class="autocomplete-light-widget" data-autocomplete-foo-bar="2" data-foo-bar="3">
<input .. />

Becomes:

.. code-block:: html

<span class="autocomplete-light-widget" data-widget-foo-bar="3">
<input data-autocomplete-foo-bar="2" ... />
18 changes: 15 additions & 3 deletions docs/source/index.rst
Expand Up @@ -28,9 +28,21 @@ If you didn't click any, and this is your first install: bravo !
Upgrade
-------

Run ``pip install -U django-autocomplete-light``. Check the CHANGELOG for BC
(Backward Compatibility) breaks. There should be none for minor version
upgrades ie. from 1.1.3 to 1.1.22.
v1 to v2
````````

.. toctree::
:maxdepth: 3

1to2

Other upgrades
``````````````

Run ``pip install -U django-autocomplete-light``. Check the CHANGELOG
for BC (Backward Compatibility) breaks. There should be none for minor
version upgrades ie. from 1.1.3 to 1.1.22, but there might be some
minor BC breaks for middle upgrades ie. 1.2.0 to 1.3.0.

Quick start
-----------
Expand Down

0 comments on commit ebfb01a

Please sign in to comment.