每当我和你的编辑的对象一个与外国的关键目B,加选项"添加一个"可用接下来的选择的对象B。我怎么删除该选项吗?

我配置的用户没有权利增加对象B。加号是仍然可用,但是,当我点击,它说,"许可拒绝"。这是丑陋的.

我使用的Django1.0.2

有帮助吗?

解决方案

DEPRECATED ANSWER

Django的自使之成为可能。


你有没有考虑,而不是使用CSS来根本不显示按钮?也许这是一个有点哈克。

这是未经测试,但我想...

无addanother-button.css

#_addanother { display: none }

admin.py

class YourAdmin(admin.ModelAdmin):
    # ...
    class Media:
        # edit this path to wherever
        css = { 'all' : ('css/no-addanother-button.css',) }

Django的文件这样做的 - 媒体作为静态定义

注意/编辑:的文件说,这些文件将与MEDIA_URL预先考虑,但在我的实验事实并非如此。大小可能不同。

如果你发现这是你的情况下,有这种速战速决...

class YourAdmin(admin.ModelAdmin):
    # ...
    class Media:
        from django.conf import settings
        media_url = getattr(settings, 'MEDIA_URL', '/media/')
        # edit this path to wherever
        css = { 'all' : (media_url+'css/no-addanother-button.css',) }

其他提示

(停止upvoting这个错误答案!!!)

勘误表:这个答案基本上是错误的,不回答OP的问题。见下文。

  

(这是仅适用于内联形式,OP要求不外键字段)

     

简单的解决方案,没有CSS破解,没有编辑Django的基本代码:

     

添加到您的在线类:

     

max_num=0

<强>更新

这不回答OP的问题,按要求是仅仅是为了掩盖“添加相关”按钮内嵌的形式,而不是外键有用。

在我写这个答案,这个都接受的答案都隐藏,这就是为什么我弄糊涂了。

以下链接似乎提供了解决方案(尽管使用CSS隐藏似乎是最可行的事情要做,特别是如果以串联形式“添加其他” FKS的按钮):

Django的1.7去除内嵌形式

虽然大多数在这里提到的解决方案的工作,有是做它的另一个更清洁的方式。有人大概在Django的更高版本推出,其他的解决措施后。 (我目前使用Django 1.7)

要去除 “添加其他” 选项,

class ... #(Your inline class)

    def has_add_permission(self, request):
        return False

同样的,如果你想禁用“删除?”选项,添加以串联类下面的方法。

    def has_delete_permission(self, request, obj=None):
        return False

N.B。适用于Django的1.5.2和可能更老。该can_add_related财产出现大约2年前。

我发现最好的办法是重写你的ModelAdmin的get_form功能。在我的情况,我想强制帖子的作者是当前登录的用户。用大量的评论下面的代码。真正重要的位是widget.can_add_related的设置:

def get_form(self,request, obj=None, **kwargs):
    # get base form object    
    form = super(BlogPostAdmin,self).get_form(request, obj, **kwargs)

    # get the foreign key field I want to restrict
    author = form.base_fields["author"]

    # remove the green + by setting can_add_related to False on the widget
    author.widget.can_add_related = False

    # restrict queryset for field to just the current user
    author.queryset = User.objects.filter(pk=request.user.pk)

    # set the initial value of the field to current user. Redundant as there will
    # only be one option anyway.
    author.initial = request.user.pk

    # set the field's empty_label to None to remove the "------" null 
    # field from the select. 
    author.empty_label = None

    # return our now modified form.
    return form

在这里做出的变化get_form有趣的部分是,author.widgetdjango.contrib.admin.widgets.RelatedFieldWidgetWrapper的一个实例,其中,如果你尝试,并在的formfield_for_xxxxx功能的一个变化,小部件的实际表单控件的一个实例,在这个典型的ForeignKey的情况下,它是一个django.forms.widgets.Select

django.contrib.admin.options.py并检查了BaseModelAdmin类,formfield_for_dbfield方法。

您将看到:

# For non-raw_id fields, wrap the widget with a wrapper that adds
# extra HTML -- the "add other" interface -- to the end of the
# rendered output. formfield can be None if it came from a
# OneToOneField with parent_link=True or a M2M intermediary.
if formfield and db_field.name not in self.raw_id_fields:
    formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site)

我认为最好的方法是创建ModelAdmin(这又是BaseModelAdmin的子类)的子类,立足于新的类,覆盖formfield_fo_dbfield你的模型,并使它所以它不会/或将有条件地包住小部件在RelatedFieldWidgetWrapper

有人可能会说,如果你有没有权利将相关对象的用户,该RelatedFieldWidgetWrapper不应该显示的添加链接?也许这是这是值得一提中 Django的TRAC

我使用以下方法的表格和<强> InlineForm

2.0的Django,Python的3 +

<强>表格

class MyModelAdmin(admin.ModelAdmin):
    #...
    def get_form(self,request, obj=None, **kwargs):

        form = super().get_form(request, obj, **kwargs)
        user = form.base_fields["user"]

        user.widget.can_add_related = False
        user.widget.can_delete_related = False
        user.widget.can_change_related = False

        return form  

<强>内嵌表格

class MyModelInline(admin.TabularInline):
    #...
    def get_formset(self, request, obj=None, **kwargs):

        formset = super().get_formset(request, obj, **kwargs)
        user = formset.form.base_fields['user']

        user.widget.can_add_related = False
        user.widget.can_delete_related = False
        user.widget.can_change_related = False

        return formset

答案 @滑 表示 如何 实施解决方案,即。由压倒一切的属性formfield的部件,但是,在我看来, get_form 是不是最合乎逻辑的地方做到这一点。

答案 @cethegeek 表示 哪里 实施解决方案,即。在扩展的 formfield_for_dbfield, 但没有提供一个明确的例子。

为什么使用 formfield_for_dbfield?它的 文档字符串 表明,它指定钩搞乱的形式领域:

钩,用于指定的形式领域的实例,对于给定的数据库领域的实例。

它还允许(略)清洁和更明确的代码,而且,作为奖励,我们可以很容易地设置额外的形式 Field 属性, 如 initial 值和/或 disabled (例 在这里,),通过增加他们的 kwargs (话之前 super).

因此,结合两个答案(假定该运的模型 ModelAModelB, , ForeignKey 模型领域的命名 b):

class ModelAAdmin(admin.ModelAdmin):
    def formfield_for_dbfield(self, db_field, request, **kwargs):
        # optionally set Field attributes here, by adding them to kwargs
        formfield = super().formfield_for_dbfield(db_field, request, **kwargs)
        if db_field.name == 'b':
            formfield.widget.can_add_related = False
            formfield.widget.can_change_related = False
            formfield.widget.can_delete_related = False
        return formfield

# Don't forget to register...
admin.site.register(ModelA, ModelAAdmin)

注:如果的 ForeignKey 模型领域已 on_delete=models.CASCADE, , can_delete_related 属性 False 默认情况下,可以看出在 来源 对于 RelatedFieldWidgetWrapper.

我使用的Django2.x和我想我找到最好的解决办法,至少对我的情况。

HTML文件"保存和另外添加"按钮上 your_python_installation\Lib\site-packages\django\contrib\admin\templates\admin\subtmit_line.html.

  1. 复制那html文件和粘贴到项目一样 your_project\templates\admin\submit_line.html.
  2. 打开它,并评论/删除的按钮的代码如所期望的:

{#{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}#}

我知道这个问题已经回答。但也许有人在今后有类似情况下的跟我来。

基于cethegeek答案我在此

class SomeAdmin(admin.ModelAdmin):
    form = SomeForm

    def formfield_for_dbfield(self, db_field, **kwargs):
        formfield = super(SomeAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'some_m2m_field':
            request = kwargs.pop("request", None)
            formfield = self.formfield_for_manytomany(db_field, request, **kwargs)  # for foreignkey: .formfield_for_foreignkey
            wrapper_kwargs = {'can_add_related': False, 'can_change_related': False, 'can_delete_related': False}
            formfield.widget = admin.widgets.RelatedFieldWidgetWrapper(
                formfield.widget, db_field.remote_field, self.admin_site, **wrapper_kwargs
            )
        return formfield

django.contrib.admin.widgets.py

(Django的安装目录)/django/contrib/admin/widgets.py:评论一切线239&244之间的线:

 if rel_to in self.admin_site._registry: # If the related object has an admin interface:
        # TODO: "id_" is hard-coded here. This should instead use the correct
        # API to determine the ID dynamically.
        output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
            (related_url, name))
        output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="%s"/></a>' % (settings.ADMIN_MEDIA_PREFIX, _('Add Another')))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top