Функциональность всплывающего окна администратора Django - PullRequest
9 голосов
/ 27 февраля 2010

Эта тема является довольно распространенной (наиболее подробно изложена здесь: http://www.hoboes.com/Mimsy/hacks/replicating-djangos-admin/),, но у меня все еще возникают проблемы с ней. Я пытаюсь использовать функциональные возможности кнопки «плюс», используемые на сайте администратора, где можно добавить дополнительный внешний ключ к связанной записи. На сайте администратора отображается всплывающее окно, позволяющее пользователю отправить новое поле, а затем это новое значение заполняется в исходной форме.

Я думаю, что моя проблема сосредоточена вокруг включения этой строки:

внутри шаблона base.html и шаблона popadd.html. Нажатие кнопки «плюс» не открывает новое окно. Шаблон popadd просто загружается в ту же вкладку. И отправка новой записи не возвращает пользователя к исходной форме.

Администратор сайта функционирует. Я включаю ADMIN_MEDIA_PREFIX = '/ media / admin /' в файл settings.py. Это как-то связано с тем, где живет RelatedObjectLookups.js? В настоящее время он находится в папке администратора за пределами папки моего проекта. Нужно ли создавать символическую ссылку?

Извините за нубские вопросы. Буду признателен за любые предложения (как можно более подробно).

Ответы [ 4 ]

7 голосов
/ 01 ноября 2012

Выполнение шагов, описанных ниже, позволит вам воссоздать всплывающую функциональность связанных объектов администратора Django без необходимости создавать какие-либо пользовательские виджеты, представления и URL-адреса. Эти шаги предполагают, что вы пытаетесь заставить это всплывающее окно работать на вашем собственном сайте администратора, который подклассов администратора Django.

Предположим, что следующие две модели Книга и Автор , с ФК от Книги к Автору. Предположим также, что нам понадобится возможность использовать всплывающее окно Связанный объект для добавления автора при создании / редактировании книги:

[app_name] /models.py:

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=200)

Позволяет создать наш пользовательский сайт администратора:

[app_name] /sites.py:

from django.contrib.admin.sites import AdminSite

my_admin_site = AdminSite(name='my_custom_admin')

Наш пользовательский сайт администратора зарегистрирует два ModelAdmin, чтобы пользователи могли добавлять / редактировать / удалять модели Book и Author:

[app_name] /admin.py:

from django.contrib.admin.options import ModelAdmin

from [app_name].forms import BookForm # We'll create this form below
from [app_name].models import Author, Book
from [app_name].sites import my_admin_site

class BookModelAdmin(ModelAdmin):
    form = BookForm()

# Register both models to our custom admin site
my_admin_site.register(Author, ModelAdmin)
my_admin_site.register(Book, BookModelAdmin)

Теперь мы настроим BookForm, который используется в BookModelAdmin выше. Здесь происходит волшебство. Для получения дополнительной информации о API RelatedFieldWidgetWrapper, нажмите здесь :

[app_name] /forms.py:

from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
from django import forms

from [app_name].models import Book
from [app_name].sites import my_admin_site

class BookForm(forms.ModelForm):
    author = Book._meta.get_field('author').formfield(
        widget=RelatedFieldWidgetWrapper(
            Book._meta.get_field('author').formfield().widget,
            Book._meta.get_field('author').rel,
            my_admin_site,
            can_add_related=True
        )
    )

    class Meta:
        model = Book

Примечания:

  1. Вы должны будете убедиться, что эти два файла javascript включены в ваши шаблоны: admin/js/core.js и admin/js/admin/RelatedObjectLookups.js.

Gotchas:

  1. is_popup должен быть установлен и правильно передан в ваших шаблонах. В частности, в любых пользовательских шаблонах change_form.html, которые вы переопределяете, вы должны не забыть добавить эту строку где-нибудь внутри тегов формы: {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}, чтобы логика в BaseModelAdmin.response_add() возвращала правильный ответ.

Под капотом: По сути, мы повторно используем логику обработки форм, оболочку виджетов и javascript, которые уже включены в админку Django.

  1. Использование RelatedFieldWidgetWrapper для переноса виджета, связанного с полем связанного объекта в нашей форме (и, в частности, передача can_add_related=True в конструкторе), говорит виджету добавить необходимую ссылку '+' с соответствующим событием onclick javascript, прикрепленным к это.
  2. Javascript администратора Django обрабатывает всю логику, необходимую для запуска всплывающего окна.
  3. Логика {% if is_popup %}...{% endif %} в наших шаблонах change_form.html и логика в BaseModelAdmin.response_add() обрабатывают сохранение нового связанного объекта и возвращают соответствующий ответ javascript, который сообщает всплывающему окну о том, что его необходимо закрыть .

Связанные репо: Этот публичный репозиторий должен предоставить пример кода для проекта Django, который обсуждался выше: https://github.com/cooncesean/Books

5 голосов
/ 20 октября 2010

Я также создал приложение, которое вы можете просто включить в свой проект на http://github.com/sontek/django-tekextensions

4 голосов
/ 21 марта 2014

Google указал мне на эту страницу при поиске, как получить значок "+" рядом с полями в пользовательской форме с отношением ForeignKey (как это сделал бы сайт администратора), поэтому я решил добавить.

Для меня с помощью django-autocomplete-light все получилось, используя функцию «добавить еще». Смотрите это живое демо .

См. Django ModelChoiceField также не имеет кнопки плюса .

2 голосов
/ 03 июля 2017

Если в admin вы хотите отобразить связанные объекты в модалах вместо старых всплывающих окон Я предлагаю вам попробовать django-admin-interface.

Чтобы установить его, выполните следующие действия:

  • pip install django-admin-interface
  • Добавить admin_interface, flat_responsive и colorfield к settings.INSTALLED_APPS до django.contrib.admin
  • python manage.py migrate
  • python manage.py collectstatic

Для получения более подробной информации см. django-admin-interface на GitHub.

...