Django 管理弹出功能

2023-10-01前端开发问题
33

本文介绍了Django 管理弹出功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

这个话题相当普遍(最明确的细节在这里:http://www.hoboes.com/Mimsy/hacks/replicating-djangos-admin/),但我仍然遇到问题.我正在尝试使用管理站点中使用的加号"按钮功能,可以在其中向链接条目添加额外的外键.在管理站点中,将显示一个弹出窗口,允许用户提交一个新字段,然后在原始表单中填充该新值.

This topic is fairly common (most explicitly detailed here: http://www.hoboes.com/Mimsy/hacks/replicating-djangos-admin/), but I'm still having trouble with it. I'm trying to use the "plus" button functionality used in the admin site where one can add an additional foreign key to a linked entry. In the admin site, a popup displays allowing the user to submit a new field and then that new value is populated on the original form.

我认为我的问题集中在包含这一行:

I think my issue centers around the inclusion of this line:

在 base.html 模板和 popadd.html 模板中.单击加号按钮不会打开新窗口.popadd 模板只是在同一个选项卡中加载.并且提交新条目不会让用户回到原来的表单.

within the base.html template and the popadd.html template. Clicking the plus button does not bring up a new window. The popadd template simply loads in the same tab. And submitting a new entry does not take the user back to the original form.

管理站点正常运行.我在 settings.py 文件中包含 ADMIN_MEDIA_PREFIX = '/media/admin/' .它与 RelatedObjectLookups.js 所在的位置有关吗?它目前位于我的项目文件夹之外的管理目录中.我必须创建一个符号链接吗?

The admin site is functional. I am including ADMIN_MEDIA_PREFIX = '/media/admin/' in the settings.py file. Does it have something to do with where the RelatedObjectLookups.js lives? It's currently in an admin directory outside of my project folder. Do I have to create a symlink?

对不起,菜鸟问题.希望有任何建议(尽可能详细).

Sorry for the noob questions. Would appreciate any suggestions (as detailed as possible).

推荐答案

按照下面概述的步骤,您可以重新创建 Django 管理员的相关对象弹出功能,而无需创建任何自定义小部件、视图和 url.这些步骤假设您正在尝试让这个弹出窗口在您自己的自定义管理站点中工作,该站点是 Django 管理员的子类.

Following the steps outlined below will allow you to recreate Django admin's related object pop-up functionality without having to create any custom widgets, views, and urls. These steps assume you are trying to get this pop-up working in your own custom admin site which subclasses Django's admin.

让我们假设以下两个模型 BookAuthor,具有从 Book 到 Author 的 FK.还假设我们希望能够在创建/编辑书籍时使用相关对象弹出窗口来添加作者:

Lets assume the following two models Book and Author, with an FK from Book to Author. Lets also assume that we'll want the ability to use the Related Object Pop-Up to add an Author when creating/editing a Book:

[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)

让我们创建我们的自定义管理站点:

Lets create our custom admin site:

[app_name]/sites.py:

from django.contrib.admin.sites import AdminSite

my_admin_site = AdminSite(name='my_custom_admin')

我们的自定义管理站点将注册两个 ModelAdmin 以允许用户添加/编辑/删除 Book 和 Author 模型:

Our custom admin site will register two ModelAdmins to allow users to add/edit/delete both the Book and Author models:

[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)

现在,我们将设置上面 BookModelAdmin 中使用的 BookForm.这就是魔法发生的地方.有关 RelatedFieldWidgetWrapper api 的更多信息,点击这里:

Now, we'll setup the BookForm which is used in the BookModelAdmin above. This is where the magic happens. For more info on the RelatedFieldWidgetWrapper api, click here:

[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.jsadmin/js/admin/RelatedObjectLookups.js.

陷阱:

  1. is_popup 需要在您的模板中正确设置和传递.具体来说,在您覆盖的任何自定义 change_form.html 模板中,您必须记住在表单标签中的某处添加此行:{% if is_popup %}<input type="hidden" name="_popup" value="1"/>{% endif %},这样BaseModelAdmin.response_add() 返回正确的响应.
  1. is_popup needs to be set and passed correctly in your templates. Specifically, in any custom change_form.html templates you override, you must remember to add this line somewhere within your form tags: {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}, so that the logic in BaseModelAdmin.response_add() returns the correct response.

幕后:本质上,我们正在重用 Django admin 中已经包含的表单处理逻辑、小部件包装器和 javascript.

Under The Hood: Essentially, we're re-using the form processing logic, widget wrapper and javascript that is already included with Django admin.

  1. 使用 RelatedFieldWidgetWrapper 在我们的表单中包装关联到相关对象字段的小部件(并特别在构造函数中传递 can_add_related=True)告诉小部件附加必要的带有相应 javascript onclick 事件的+"链接.
  2. Django 管理员的 javascript 处理启动弹出窗口所需的所有逻辑.
  3. 我们的 change_form.html 模板中的 {% if is_popup %}...{% endif %} 逻辑和 BaseModelAdmin 中的逻辑.response_add() 处理新相关对象的保存并返回适当的 javascript 响应,通知弹出窗口它需要关闭.
  1. Using RelatedFieldWidgetWrapper to wrap the widget associated to the related object field in our form (and specifically passing can_add_related=True in the constructor) tells the widget to append the necessary '+' link with the appropriate javascript onclick event attached to it.
  2. Django admin's javascript handles all of the logic necessary to launch the pop-up.
  3. The {% if is_popup %}...{% endif %} logic in our change_form.html template(s) and the logic in BaseModelAdmin.response_add() handles the saving of the new related object and returns the appropriate javascript response that informs the pop-up that it needs to be closed.

相关回购:这个公共 repo 应该为上面讨论的 Django 项目提供示例代码:https://github.com/cooncesean/Books

Related Repo: This public repo should provide sample code for the Django project discussed above: https://github.com/cooncesean/Books

这篇关于Django 管理弹出功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

js删除数组中指定元素的5种方法
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
2024-11-22 前端开发问题
182

JavaScript小数运算出现多位的解决办法
在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会...
2024-10-18 前端开发问题
301

JavaScript(js)文件字符串中丢失"\"斜线的解决方法
问题描述: 在javascript中引用js代码,然后导致反斜杠丢失,发现字符串中的所有\信息丢失。比如在js中引用input type=text onkeyup=value=value.replace(/[^\d]/g,) ,结果导致正则表达式中的\丢失。 问题原因: 该字符串含有\,javascript对字符串进行了转...
2024-10-17 前端开发问题
437

layui 表格的默认工具栏添加自定义按钮
首先定义table: var tableIns = table.render({ elem:'#businessUserListTable' ,url: ctx+'/business/businessUser/query' ,error:admin.error ,cellMinWidth: 80// ,width:3700 ,toolbar: '#businessUserListTable-toolbar' ,defaultToolbar: [{ title: '...
2024-06-12 前端开发问题
146

layui中table列表 增加属性 edit="date",不生效怎么办?
如果你想在 layui 的 table 列表中增加 edit=date 属性但不生效,可能是以下问题导致的: 1. 缺少日期组件的初始化 如果想在表格中使用日期组件,需要在页面中引入 layui 的日期组件,并初始化: script type="text/javascript" src="/layui/layui.js"/scrip...
2024-06-11 前端开发问题
455

Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript
Rails/Javascript: How to inject rails variables into (very) simple javascript(Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript)...
2024-04-20 前端开发问题
5