После шагов, описанных ниже, позволит вам воссоздать соответствующий объект всплывающей функциональность Джанго админа без создания каких-либо пользовательских виджетов, просмотров и URL-адресов. Эти шаги предполагают, что вы пытаетесь открыть это всплывающее окно в своем собственном админ-сайте, который подклассифицирует администратор Django.
Давайте предположат, что следующие две моделей на сайте и Автор, с FK из книги автора. Позволяет также предположить, что мы хотим возможность использовать Связанные объекта Pop-Up добавить Автор при создании/редактировании книги:
[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')
Наш пользовательский администратор сайта будет зарегистрировать два ModelAdmins, чтобы позволить пользователям добавлять/редактировать/удалять обе модели книги и Автор:
[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)
Теперь мы 'll setup BookForm
, который используется в BookModelAdmin
выше. Здесь происходит волшебство. Для получения дополнительной информации о RelatedFieldWidgetWrapper api, click here:
[имя_приложения]/формы.ру:
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
Примечания:
- Вы должны убедиться, что эти два JavaScript-файлы, включенные в шаблонах:
admin/js/core.js
и admin/js/admin/RelatedObjectLookups.js
.
Gotchas:
is_popup
необходимо задать и передается правильно в шаблонах. В частности, в любых настраиваемых шаблонах change_form.html
вы должны запомнить эту строку где-то в ваших тегах формы: {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}
, чтобы логика в BaseModelAdmin.response_add()
вернула правильный ответ.
Under The Hood: По существу, мы повторно использовать логику обработки форм, виджетов обертку и JavaScript, который уже входит в Django администратора.
- Использование
RelatedFieldWidgetWrapper
обернуть виджет, связанный с соответствующей предметной областью в нашей форме (а именно прохождение can_add_related=True
в конструкторе) рассказывает виджет для добавления необходимого «+» связи с подходящим яваскриптом OnClick события прикрепленного к нему ,
- javascript администратора Django обрабатывает всю логику, необходимую для запуска всплывающего окна.
- Логика в нашем
change_form.html
шаблонах (шаблонов) и логике в BaseModelAdmin.response_add()
обрабатывает сохранение нового связанного объекта и возвращает соответствующий ответ javascript, который информирует всплывающее окно, которое необходимо закрыть.
Связанные Repo: Это публичное репо должен предоставить образец кода для проекта Django рассмотренном выше: https://github.com/cooncesean/Books
Какой браузер вы используете? Какие плагины (если есть) вы установили и как они настроены? В FF * Tab Mix Plus * (среди прочих) способна радикально изменять поведение всплывающего окна/нового окна. –
Я использую firefox. Но я не думаю, что это связано с плагинами/конфигурацией. Функциональность администратора прекрасно работает на сайте администратора. Когда я пытаюсь использовать его вне этой структуры, я не могу заставить его работать правильно. –