Django Admin弹出功能

时间:2010-02-27 14:06:25

标签: javascript django popup admin

这个主题很常见(这里最明确的详细说明:http://www.hoboes.com/Mimsy/hacks/replicating-djangos-admin/),但我仍然遇到问题。我正在尝试使用管理站点中使用的“加号”按钮功能,可以在链接条目中添加其他外键。在管理站点中,会显示一个弹出窗口,允许用户提交新字段,然后在原始表单上填充该新值。

我认为我的问题围绕着这一行:

在base.html模板和popadd.html模板中。单击加号按钮不会显示新窗口。 popadd模板只需加载到同一个选项卡中。并且提交新条目不会将用户带回原始表单。

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

对于noob问题抱歉。非常感谢任何建议(尽可能详细)。

4 个答案:

答案 0 :(得分:6)

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

让我们假设以下两个模型 Book 作者,以及从Book到Author的FK。让我们假设我们希望能够在创建/编辑图书时使用相关对象弹出添加作者:

<强> [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。这就是魔术发生的地方。有关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
  2. <强>陷阱:

    1. is_popup需要在模板中正确设置和传递。具体来说,在您覆盖的任何自定义change_form.html模板中,您必须记住在表单标记中的某处添加此行:{% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %},以便BaseModelAdmin.response_add()中的逻辑返回正确的响应。
    2. Under The Hood: 基本上,我们正在重新使用Django管理员已经包含的表单处理逻辑,小部件包装器和javascript。

      1. 使用RelatedFieldWidgetWrapper包装与表单中相关对象字段关联的窗口小部件(特别是在构造函数中传递can_add_related=True)告诉窗口小部件使用相应的javascript附加必要的“+”链接onclick事件附加到它。
      2. Django admin的javascript处理启动弹出窗口所需的所有逻辑。
      3. {% if is_popup %}...{% endif %}模板中的change_form.html逻辑和BaseModelAdmin.response_add()中的逻辑处理新相关对象的保存并返回通知弹出窗口的相应javascript响应它需要关闭。
      4. 相关回购: 这个公共仓库应该为上面讨论的Django项目提供示例代码:https://github.com/cooncesean/Books

答案 1 :(得分:5)

我还在http://github.com/sontek/django-tekextensions

创建了一个可以包含在项目中的应用

答案 2 :(得分:4)

谷歌在搜索如何获得&#34; +&#34;时指向了这个页面。带有ForeignKey关系的自定义表单中的字段旁边的图标(就像管理网站一样),所以我想我会添加。

对我来说,使用django-autocomplete-light做得非常好,使用&#34;添加另一个&#34;功能。请参阅this live demo

同样请参阅Django ModelChoiceField has no plus button

答案 3 :(得分:2)

如果在管理中你想在模式中显示相关对象而不是旧的弹出窗口,我建议您尝试{{1 }}

要安装它,请按以下步骤操作:

  • var React = require('react'); var ReactNative = require('react-native'); var t = require('tcomb-form-native'); var { AppRegistry, AsyncStorage, StyleSheet, Text, View, TouchableHighlight, AlertIOS, Image, } = ReactNative; var STORAGE_KEY = 'id_token'; var Form = t.form.Form; var Person = t.struct({ username: t.String, password: t.String }); const options = {}; var AwesomeProject = React.createClass({ async _onValueChange(item, selectedValue) { try { await AsyncStorage.setItem(item, selectedValue); } catch (error) { console.log('AsyncStorage error: ' + error.message); } }, componentDidMount: function() { this._userLogin(); }, _userLogin: function() { var value = this.refs.form.getValue(); if (value) { // if validation fails, value will be null fetch("http://vowelserver.com/trades/test_autheticate/", { method: "POST", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ username: value.username, password: value.password, }) }).then((response) => response.json()) .then((responseData) => { this._onValueChange(STORAGE_KEY, responseData.id_token) }).done(); } }, render() { return ( <View style={styles.container}> <View style={styles.container}> <Image resizeMode="contain" source={{uri: 'http://res.cloudinary.com/vowelweb/image/upload/v1498114115/Logo_mqzlgt.png'}} style={styles.image} /> </View> <View style={styles.row}> <Form ref="form" type={Person} options={options} /> </View> <View style={styles.row}> <TouchableHighlight style={styles.button} onPress={this._userLogin} underlayColor='#99d9f4'> <Text style={styles.buttonText}>Login</Text> </TouchableHighlight> </View> </View> ); } }); var styles = StyleSheet.create({ container: { justifyContent: 'center', marginTop: 50, padding: 20, backgroundColor: '#ffffff', }, containers: { flex: 1, justifyContent: 'flex-start', alignItems: 'center', backgroundColor: 'white', position: 'relative', borderBottomWidth: 1, }, title: { fontSize: 30, alignSelf: 'center', marginBottom: 30 }, buttonText: { fontSize: 18, color: 'white', alignSelf: 'center' }, button: { height: 36, backgroundColor: '#48BBEC', borderColor: '#48BBEC', borderWidth: 1, borderRadius: 8, marginBottom: 10, alignSelf: 'stretch', justifyContent: 'center' }, login: { flex: 1, backgroundColor: '#efeff2', alignItems: 'center', justifyContent: 'center', }, image: { position: 'absolute', top: 0, bottom: 0, left: 30,`enter code here` right: 30, }, }); AppRegistry.registerComponent('FirstRun', () => AwesomeProject);
  • 在<{strong> django-admin-interface
  • 之前将pip install django-admin-interfaceadmin_interfaceflat_responsive添加到colorfield
  • settings.INSTALLED_APPS
  • django.contrib.admin

有关详细信息,请参阅GitHub上的django-admin-interface