Inline редактирование в Django

в 16:04, , рубрики: django, inline-edit, метки: ,

Недавно встала задача дать пользователям удобный инструмент редактирования данных. Хотелось, чтобы пользователи сразу видели результат и не прыгали между несколькими страницами для редактирования и просмотра. Немного погуглив, нашли отличное приложение 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>

И как это выглядит до редактирования:
Inline редактирование в Django
В процессе редактирования:
Inline редактирование в Django
Теперь скриншот всей страницы. Обратите внимание на textarea, там появился WYSIWYG редактор
Просмотр:
Inline редактирование в Django
В режиме редактирования:
Inline редактирование в Django
Пример редактора в шаблоне:

{% 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js