Недавно встала задача дать пользователям удобный инструмент редактирования данных. Хотелось, чтобы пользователи сразу видели результат и не прыгали между несколькими страницами для редактирования и просмотра. Немного погуглив, нашли отличное приложение django-inplaceedit, которое позволяет реализовать наглядное редактирование данных.
Установка из PyPI:
pip install django-inplaceedit
Подключаем приложение к проекту в settings.py:
INSTALLED_APPS = (
....
'inplaceeditform',
)
TEMPLATE_CONTEXT_PROCESSORS = (
#...#
'django.core.context_processors.request',
#...#
)
Это настройки, которе мы использовали, в документации их больше
ADAPTOR_INPLACEEDIT_EDIT = 'my_app.perms.MyAdaptorEditInline' # "подключаем свой perms.py, подробнее - ниже"
INPLACEEDIT_DISABLE_CLICK = False # "разрешаем сохранять изменения нажатием Enter"
THUMBNAIL_DEBUG = True
INPLACEEDIT_EVENT = "click" # "событие для вызова редактирования"
Определение своих адаптеров или переопределение дефолтных.
Зачем это может понадобиться? Есть расширение для django-inplaceedit, django-inplaceedit-extra-fields добавляющее работу с AutoCompleteManyToManyField и AutoCompleteForeingKeyField. Названия адаптеров в обоих приложениях могут совпадать и тогда мы можем их переопределить. Или же можно написать свой адаптер.
ADAPTOR_INPLACEEDIT = {'auto_fk': 'inplaceeditform_extra_fields.fields.AdaptorAutoCompleteForeingKeyField',
'auto_m2m': 'inplaceeditform_extra_fields.fields.AdaptorAutoCompleteManyToManyField',
'image_thumb': 'inplaceeditform_extra_fields.fields.AdaptorImageThumbnailField',
'tiny': 'inplaceeditform_extra_fields.fields.AdaptorTinyMCEField',}
Подключение в base.html
{% load inplace_edit %}
{% inplace_toolbar %}
or
{% inplace_static %}
Подключение в urls.py
urlpatterns = patterns('',
#...#
(r'^inplaceeditform/', include('inplaceeditform.urls')),
#...#
)
Определения прав редактирования
По умолчанию, редактировать информацию с помощью django-inplaceedit может только superuser. Это легко исправить с помощью переопределения прав. Помните, выше мы описывали
ADAPTOR_INPLACEEDIT_EDIT = 'my_app.perms.MyAdaptorEditInline'
теперь подробнее.
Создаем файл perms.py внутри my_app. Вот файл из документации
class MyAdaptorEditInline(object):
@classmethod
def can_edit(cls, adaptor_field):
user = adaptor_field.request.user
obj = adaptor_field.obj
can_edit = False
if user.is_anonymous():
pass
elif user.is_superuser:
can_edit = True
else:
can_edit = has_permission(obj, user, 'edit')
return can_edit
у себя же я всю проверку вынес до загрузки шаблона с inlineedit, поэтому мой файл проще
class MyAdaptorEditInline(object):
@classmethod
def can_edit(cls, adaptor_field):
can_edit = True
return can_edit
Использование в шаблоне редактирования
{% extends "base.html" %}
{% load i18n inplace_edit %}
...
<fieldset>
<legend><span class="has-tip tip-top" data-width="300" title="Этот блок отображает Вашу персональную информацию."><wave class="social foundicon-torso"><p>Личные данные</p></wave></span></legend>
<ul class="square">
<li><p class="definition">ФИО: </p><p>{% inplace_edit "seeker.user.first_name" adaptor="tiny", auto_height=1, auto_width=1, edit_empty_value="Кликните для редактирования" %}</p></li>
<li><p class="definition">Год рождения: </p><p>{% inplace_edit "seeker.age" adaptor="text", auto_height=1, auto_width=1, edit_empty_value="Кликните для редактирования" %}</p></li>
<li><p class="definition">Город проживания: </p><p class="city">{% inplace_edit "seeker.city" adaptor="text", auto_height=1, auto_width=1, edit_empty_value="Город" %}</p></li>
</ul>
</fieldset>
И как это выглядит до редактирования:
В процессе редактирования:
Теперь скриншот всей страницы. Обратите внимание на textarea, там появился WYSIWYG редактор
Просмотр:
В режиме редактирования:
Пример редактора в шаблоне:
{% inplace_edit "seeker.resume_workexp|safe" filters_to_show="safe", adaptor="tiny", tag_name_cover="div", auto_height=1, auto_width=1, edit_empty_value="Кликните для редактирования" %}
И причем это одна и таже страница, без перезагрузки. Проверяли на пользователях, достаточно всплывающих подсказок о возможности редактирования, чтобы все разобрались с первого раза.
Возможные проблемы
В другом проекте мы использовали адаптер image_thumb, для загрузки и редактирования картинок. При попытке редактировать изображение вывалилась ошибка:
TemplateSyntaxError at /adverts/cabinet/
Invalid block tag: ‘endthumbnail’, expected ‘elif’,'else’ или ‘endif’
Решение
Ошибка возникает из-за ‘sorl.thumbnail’ которое требуется при установке django-inplaceedit-extra-fields. Мы просто нашли в исходниках django-inplaceedit-extra-fields где первый раз вызывается sorl.thumbnail и заменили вызов.
Правка fields.py пакета django-inplaceedit-extra-fields, строка 96:
from sorl import thumbnail # меняем на
from easy_thumbnails import thumbnail # не забудьте установить easy_thumbnails
Ссылки на Github:
django-inplaceedit
django-inplaceedit-extra-fields
Автор: int22h