删除“添加另一个”在 Django 管理屏幕中
每当我使用对象 B 的外键编辑对象 A 时,对象 B 的选择旁边就会出现一个加号选项“添加另一个”。如何删除该选项?
我配置了一个无权添加对象 B 的用户。加号仍然可用,但当我单击它时,它显示“权限被拒绝”。太丑了。
我正在使用 Django 1.0.2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
以下答案是我原来的答案,但它是错误的,没有回答OP的问题:
(这仅适用于内联表单,不适用于OP要求的外键字段)
上面的答案仅对隐藏内联表单的“添加相关”按钮,而不是按要求隐藏外键。
当我写下答案时,IIRC 接受的答案隐藏了两者,这就是我感到困惑的原因。
以下似乎提供了一个解决方案(尽管使用 CSS 隐藏似乎是最可行的事情,特别是如果 FK 的“添加另一个”按钮采用内联形式):
Django 1.7 从内联表单中删除添加按钮
The following answer was my original answer but it is wrong and does not answer OP's question:
(this is only applicable to inline forms, not foreign key fields as OP asked)
The above answer is only useful to hide the "add related" button for inline forms, and not foreign keys as requested.
When I wrote the answer, IIRC the accepted answer hid both, which is why I got confused.
The following seems to provide a solution (though hiding using CSS seems the most feasible thing to do, especially if the "add another" buttons of FKs are in inline forms):
Django 1.7 removing Add button from inline form
尽管这里提到的大多数解决方案都有效,但还有另一种更简洁的方法。可能是在其他解决方案提出之后,在 Django 的更高版本中引入了它。 (我目前使用的是 Django 1.7)
要删除“添加另一个”选项,
类似地,如果您想禁用“删除?”选项,在内联类中添加以下方法。
Though most of the solutions mentioned here work, there is another cleaner way of doing it. Probably it was introduced in a later version of Django, after the other solutions were presented. (I'm presently using Django 1.7)
To remove the "Add another" option,
Similarly if you want to disable "Delete?" option, add the following method in Inline class.
注意适用于 DJango 1.5.2 及可能更旧的版本。
can_add_lated
属性出现大约在 2 年前。我发现的最好方法是覆盖 ModelAdmin 的 get_form 函数。就我而言,我想强制帖子的作者是当前登录的用户。下面的代码带有大量注释。真正重要的一点是
widget.can_add_lated
的设置:在
get_form
中进行更改的有趣部分是author.widget
是一个django.contrib.admin.widgets.RelatedFieldWidgetWrapper
的实例,就像您尝试在formfield_for_xxxxx
函数之一中进行更改一样,该小部件是实际表单小部件的实例,在这个典型的ForeignKey案例中,它是一个django.forms.widgets.Select
。N.B. Works for DJango 1.5.2 and possibly older. The
can_add_related
property appeared around 2 years ago.The best way I've found is to override your ModelAdmin's get_form function. In my case I wanted to force the author of a post to be the currently logged in user. Code below with copious comments. The really important bit is the setting of
widget.can_add_related
:The interesting part of making the changes here in
get_form
is thatauthor.widget
is an instance ofdjango.contrib.admin.widgets.RelatedFieldWidgetWrapper
where as if you try and make changes in one of theformfield_for_xxxxx
functions, the widget is an instance of the actual form widget, in this typical ForeignKey case it's adjango.forms.widgets.Select
.使用以下方法
我对 Form 和 InlineForm Django 2.0、Python 3+
Form
Inline Form
I use the following approaches for Form and InlineForm
Django 2.0, Python 3+
Form
Inline Form
@Slipstream 的答案展示了如何实施该解决方案,即。通过覆盖表单字段小部件的属性,但是,在我看来,
get_form
并不是执行此操作最合乎逻辑的位置。@cethegeek 的答案显示了实施该解决方案的位置,即。在
formfield_for_dbfield
的扩展中,但没有提供明确的示例。为什么使用
formfield_for_dbfield
?它的 docstring 表明它是用于搞乱表单字段的指定钩子:它还允许(稍微)更干净和更清晰的代码,并且作为奖励,我们可以轻松设置附加表单
Field
属性,例如初始
值和/或禁用
(例如此处),将它们添加到kwargs
(在调用super)。
因此,结合两个答案(假设 OP 的模型是
ModelA
和ModelB
,并且ForeignKey
模型字段名为b):
注意:如果
ForeignKey
模型字段具有on_delete=models.CASCADE
,则can_delete_lated
属性为False
默认情况下,如 RelatedFieldWidgetWrapper 的>源代码。The answer by @Slipstream shows how to implement the solution, viz. by overriding the attributes for the formfield's widget, but, in my opinion,
get_form
is not the most logical place to do this.The answer by @cethegeek shows where to implement the solution, viz. in an extension of
formfield_for_dbfield
, but does not provide an explicit example.Why use
formfield_for_dbfield
? Its docstring suggests that it is the designated hook for messing with form fields:It also allows for (slightly) cleaner and clearer code, and, as a bonus, we can easily set additional form
Field
attributes, such asinitial
value and/ordisabled
(example here), by adding them to thekwargs
(before callingsuper
).So, combining the two answers (assuming the OP's models are
ModelA
andModelB
, and theForeignKey
model field is namedb
):NOTE: If the
ForeignKey
model field hason_delete=models.CASCADE
, thecan_delete_related
attribute isFalse
by default, as can be seen in the source forRelatedFieldWidgetWrapper
.查看 django.contrib.admin.options.py 并查看 BaseModelAdmin 类、formfield_for_dbfield 方法。
您会看到这一点:
我认为您最好的选择是创建
ModelAdmin
的子类(它又是BaseModelAdmin
的子类),将您的模型基于该新类,覆盖 < code>formfield_fo_dbfield 并使其不会/或有条件地将小部件包装在RelatedFieldWidgetWrapper
中。有人可能会说,如果您的用户无权添加相关对象,那么
RelatedFieldWidgetWrapper
不应该显示添加链接?也许这是值得在 Django trac 中提及的东西?Look at
django.contrib.admin.options.py
and check out theBaseModelAdmin
class,formfield_for_dbfield
method.You will see this:
I think your best bet is create subclass of
ModelAdmin
(which in turn is a subclass ofBaseModelAdmin
), base your model on that new class, overrideformfield_fo_dbfield
and make it so that it won't/or will conditionally wrap the widget inRelatedFieldWidgetWrapper
.One could argue that if you have a user that doesn't have rights to adding related objects, the
RelatedFieldWidgetWrapper
should not display the add link? Maybe this is something that is deserving of mention in Django trac?已弃用的答案
Django 使这成为可能。
您是否考虑过使用 CSS 来简单地不显示按钮?也许这有点太hacky了。
这是未经测试的,但我在想...
no-addanother-button.css
admin.py
用于执行此操作的 Django 文档 - 媒体作为静态定义
注意/编辑:
如果您发现您遇到这种情况,可以快速解决此问题...
DEPRECATED ANSWER
Django has since made this possible.
Have you considered instead, using CSS to simply not show the button? Maybe that's a little too hacky.
This is untested, but I'm thinking...
no-addanother-button.css
admin.py
Django Doc for doing this -- Media as a static definition
Note/Edit: The documentation says the files will be prepended with the MEDIA_URL but in my experimentation it isn't. Your mileage may vary.
If you find this is the case for you, there's a quick fix for this...
我正在使用 Django 2.x,我认为我找到了最好的解决方案,至少对于我的情况来说是这样。
“保存并添加另一个”按钮的 HTML 文件位于
your_python_installation\Lib\site-packages\django\contrib\admin\templates\admin\subtmit_line.html
。your_project\templates\admin\submit_line.html
。{#{% if show_save_and_add_another %}{% endif %}#}
我知道这个问题已经得到解答。但也许将来有人会遇到和我类似的情况。
I'm using Django 2.x and I think I found best solution, at least for my case.
The HTML file to the "Save and Add Another" button is on
your_python_installation\Lib\site-packages\django\contrib\admin\templates\admin\subtmit_line.html
.your_project\templates\admin\submit_line.html
.{#{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}#}
I know this problem is already answered. But maybe someone in the future have a similar case with me.
根据 cethegeek 的回答,我做了这个:
Based on cethegeek answer I made this:
我根据 django 文档修复类似情况的方式
https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.extra
该解决方案的结果是它允许您添加内联只是为了这个例子。或者换句话说:添加一个内联并且只添加一个;没有其他按钮。
The way i fixed a similar situation based on django docs
https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.extra
The outcome of the solution is that it lets you add an inline just for that instance. Or in different words: add an inline and just one; no other buttons.
正如评论中指出的:
这里也得到了证实:
https://code.djangoproject.com/ticket/13424#comment:1
PS:这也适用于内联。
As it's been pointed out in comments:
It has also been confirmed here:
https://code.djangoproject.com/ticket/13424#comment:1
PS: This also works for inlines.
django.contrib.admin.widgets.py
(Django Install Dir)/django/contrib/admin/widgets.py: 注释第 239 行和第 239 行之间的所有内容第 244 行:
django.contrib.admin.widgets.py
(Django Install Dir)/django/contrib/admin/widgets.py: Comment everything between Line 239 & Line 244: