Saltar al contenido

Django 1.7 eliminando el botón Agregar del formulario en línea

Esta es la respuesta más válida que te podemos compartir, pero estúdiala detenidamente y valora si se adapta a tu trabajo.

Solución:

Para eliminar la opción “Agregar otro”, agregue el siguiente método en la clase en línea de administración.

def has_add_permission(self, request):
    return False

Del mismo modo, si desea deshabilitar “¿Eliminar?” opción, agregue el siguiente método en la clase en línea de administración.

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

Creo que esta es una solución menos complicada que la que terminaste. Funcionó para mí, de todos modos.

Básicamente, es el equivalente en línea de lo que sugirió hacer con la anulación del obtener_formulario método de ModelAdmin. Aquí anulamos get_formset en la clase en línea, saque el formulario del formset y haga exactamente lo mismo. Parece funcionar bien, al menos en 1.9, que estoy usando.

class VersionEntryInline(admin.TabularInline):
    template = 'admin/edit_inline/tabular_versionentry.html'
    model = VersionEntry
    extra = 0

    def get_formset(self, request, obj=None, **kwargs):
        """
        Override the formset function in order to remove the add and change buttons beside the foreign key pull-down
        menus in the inline.
        """
        formset = super(VersionEntryInline, self).get_formset(request, obj, **kwargs)
        form = formset.form
        widget = form.base_fields['project'].widget
        widget.can_add_related = False
        widget.can_change_related = False
        widget = form.base_fields['version'].widget
        widget.can_add_related = False
        widget.can_change_related = False
        return formset

Después de un par de días intensos, finalmente logré encontrar la manera de lograrlo.

Un truco simple como este es más que suficiente cuando se trata de este problema dentro de las subclases de ModelAdmin (ver ClienteAdmin en mi código anterior), así que aquí está la versión de clase sin agregar capacidades para el campo “Prodotto”:

@admin.register(Cliente)
class ClienteAdmin(admin.ModelAdmin):
    list_display = [
        'ragione_sociale', 'forma_societaria', 'titolare', 'partita_iva', ]
    list_filter = ['forma_societaria', ]
    search_fields = ['ragione_sociale', ]
    inlines = [RecapitoInline, SedeInline]
    def get_form(self, request, obj=None, **kwargs):    # Just added this override
        form = super(ClienteAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['prodotto'].widget.can_add_related = False
        return form

El verdadero problema surge cuando se trata de clases en línea (TabularInline, StackedInline), ya que parece que la función get_form() no se llama en absoluto, por lo que la forma anterior no funcionará.

Explicar todos mis intentos anteriores llevaría demasiado tiempo, y probablemente ni siquiera soy lo suficientemente bueno con Django para decir por qué no funcionaron. Así que vayamos directamente a la solución, que de hecho ni siquiera es tan complicada.

yo subclasificaba django.contrib.admin.widgets.RelatedFieldWidgetWrapper widget y anuló su método de representación, de modo que no agregue el ancla “agregar otro” a la salida. Se hace fácilmente comentando algunas líneas. Después de hacerlo, parcheé el RelatedFieldWidgetWrapper original con mi propia versión (django.contrib.admin.widgets.RelatedFieldWidgetWrapper = Sin agregarRelatedFieldWidgetWrapper) hizo el truco.

Claramente, para que funcionara, tuve que agregar la línea de importación en el administrador.py:

de .widgets importar NoAddingRelatedFieldWidgetWrapper

widgets.py

import django.contrib.admin.widgets
from django.utils.safestring import mark_safe


class NoAddingRelatedFieldWidgetWrapper(django.contrib.admin.widgets.RelatedFieldWidgetWrapper):

    def render(self, name, value, *args, **kwargs):
        from django.contrib.admin.views.main import TO_FIELD_VAR
        rel_to = self.rel.to
        info = (rel_to._meta.app_label, rel_to._meta.model_name)
        self.widget.choices = self.choices
        output = [self.widget.render(name, value, *args, **kwargs)]
        '''
        if self.can_add_related:
            related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)
            url_params = '?%s=%s' % (TO_FIELD_VAR, self.rel.get_related_field().name)
            # TODO: "add_id_" is hard-coded here. This should instead use the
            # correct API to determine the ID dynamically.
            output.append(' '
                          % (related_url, url_params, name))
            output.append('%s
' % (static('admin/img/icon_addlink.gif'), _('Add Another'))) ''' return mark_safe(''.join(output)) # Monkeypatch django.contrib.admin.widgets.RelatedFieldWidgetWrapper = NoAddingRelatedFieldWidgetWrapper

En aras de completar, aquí está la versión final del admin.py relacionado:

administrador.py

from django.contrib import admin
import django.contrib.admin.widgets

from django.db import models

from .models import Cliente, Prodotto, Sede
from apps.recapito.models import RecapitoCliente
from .widgets import NoAddingRelatedFieldWidgetWrapper


class SedeInline(admin.TabularInline):
    model = Sede
    extra = 1

    def provincia(self, obj):
        return obj.comune.provincia

    readonly_fields = ['provincia', ]


class RecapitoInline(admin.TabularInline):
    model = RecapitoCliente
    extra = 1
    readonly_fields = ['cliente', 'tipo', 'recapito', ]


@admin.register(Cliente)
class ClienteAdmin(admin.ModelAdmin):
    list_display = [
        'ragione_sociale', 'forma_societaria', 'titolare', 'partita_iva', ]
    list_filter = ['forma_societaria', ]
    search_fields = ['ragione_sociale', ]
    inlines = [RecapitoInline, SedeInline]
    def get_form(self, request, obj=None, **kwargs):
        form = super(ClienteAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['prodotto'].widget.can_add_related = False
        return form

Si alguien presenta una solución mejor, con gusto la aceptaré en lugar de la mía.

No se te olvide mostrar esta reseña si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *