Django 1.7从内联形式移除添加按钮 [英] Django 1.7 removing Add button from inline form

查看:247
本文介绍了Django 1.7从内联形式移除添加按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实现(可能)相当简单的任务时遇到问题。
我有完全可修改的模型(Prodotto,Comune),显示为可添加字段,如下图所示。
我不希望看到的是这个字段的+(添加)按钮,因此可以删除这个表单中的可添加适当性。
我已经尝试在两个模型中设置 has_add_permission = False ,但是它不会将这个模型完全添加到新的对象中,而不仅仅是这种形式。



我该怎么做?



编辑:为了澄清我的需要,我不想在FK模型的字段旁边有+,但是我仍然希望能够添加全新的内联。为了尽可能清楚,正如我在评论中写的,考虑一个这样的场景: https://code.djangoproject.com/attachment/ticket/20367/django_custom_user_admin_form.png 我只需要删除组和国家旁边的+。



现有代码



models.py (涉及的具体应用程序) :

 $ d code从django.db导入模型

from smart_selects.db_fields import ChainedForeignKey

from apps.comune.models import Comune,Cap


class Prodotto(models.Model):
SETTORE_CHOICES =(
('CAL',' (A,Auto e moto),
('ALI','Alimentari'),
('ARA','Arredamenti e accessori'),

('CAL','Calzature'),
('CEG','Cartaria e grafica'),
('CEP','Concerie e pelletterie'),
('EDI','Edilizia'),
('INV','Industrie varie'),
('IST','Istruzione'),
('MDC','Materiali da costruzione'),
('MMC' ''''''''''
('SEI','Serramenti e infissi'),
('STM','Strumenti musicali'),
('TEI','Terziario innovativo') ,
('TAB','Tessile abbigliamento'),
('TCP','Trasporto cose e persone'),
('VAR','Vari'),

nome = models.CharField(max_length = 100)
settore = models.CharField(max_length = 40,choices = SETTORE_CHOICES)

class Meta:
verbose_name_plural =prodotti
verbose_name =prodotto
ordering = ['nome']

def __unicode __(self):
ret urn self.nome.capitalize()


class Cliente(models.Model):
TIPOLOGIA_CHOICES =(
('AR','Artigiano'),
('CO','Commerciante'),
('GI','Grande impresa'),
('PI','Piccola impresa'),

FORMA_SOCIETARIA_CHOICES =(
('SNC','Snc'),
('SRL','Srl'),
('SPA','SpA'),
('SAS','Sas'),
('COOP','Coop.Arl'),
('DI','DI'),
('SCARL' 'sca'',
('SCPA','Scpa'),

SETTORE_CHOICES =(
('CAL','Accessori calzature'),
('ALI','Alimentari'),
('ARA','Arredamenti e accessori'),
('AEM','Auto e moto'),
('CAL' ,'Calzature'),
('CEG','Cartaria e grafica'),
('CEP','Concerée pelletterie'),
('EDI','Edilizia'),
('INV','Industrie varie'),
'IST','Istruzione'),
('MDC','Materiali da costruzione'),
('MMC','Metalmeccanica'),
('SEI','Serramenti e'b $ b('STM','Strumenti musicali'),
('TEI','Terziario innovativo'),
('TAB','Tessile abbigliamento'),
('TCP','Trasporto cose e persone'),
('VAR','Vari'),

ragione_sociale = models.CharField(max_length = 200)
forma_societaria = models.CharField(
max_length = 5,choices = FORMA_SOCIETARIA_CHOICES)
titolare = models.CharField(max_length = 100,blank = True)
partita_iva = models.CharField
max_length = 11,verbose_name ='Partita IVA',unique = True)
tipologia = models.CharFi eld(max_length = 2,choices = TIPOLOGIA_CHOICES)
settore = models.CharField(max_length = 40,choices = SETTORE_CHOICES)
prodotto = models.ManyToManyField(Prodotto,blank = True)

class Meta:
verbose_name_plural =clienti
verbose_name =cliente

def __unicode __(self):
return self.ragione_sociale.capitalize()


class Sede(models.Model):
nome = models.CharField(max_length = 100)
indirizzo = models.CharField(max_length = 200,blank = True )
cliente = models.ForeignKey(Cliente)
comune = models.ForeignKey(Comune)
cap = ChainedForeignKey(
Cap,
chained_field =comune,
chained_model_field =comune,
show_all = False,
auto_choose = True,


class Meta:
verbose_name_plural =sedi
verbose_name =sede
ordering = ['nome']

def _ _unicode __(self):
return self.nome.capitalize()+,+ self.indirizzo

admin.py (涉及的具体应用程序):

  from django.contrib导入admin 

从.models import Cliente,Prodotto,Sede
from apps.recapito.models import RecapitoCliente


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
list_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]


admin.site.register(Prodotto)

此应用程序的管理界面产生:





快捷链接1和2是我需要删除的,被引用到我的内联类中的列(FKs)
快捷链接3和4将被保留,因为它们自己引用内嵌

解决方案

我认为这是一个比你最后的一个更简洁的解决方案。无论如何,它为我工作。



基本上,它是与您建议使用的重写ModelAdmin的 get_form 方法的内联等价物。这里我们覆盖内联类中的 get_formset ,从窗体集中获取表单,并执行完全相同的操作。似乎工作正常,至少在1.9,我正在使用。

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

def get_formset(self,request,obj = None,** kwargs)

覆盖formset函数,以便删除内联旁边的外键下拉
菜单旁边的添加和更改按钮

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


I'm having problems achieving a (probably) rather simple task. I have fully modifiable models (Prodotto, Comune) which are shown as "addable" fields, as shown in picture below. What I'd rather not see is the + (add) button for such fields, hence to remove their "addable" propriety in this form. I've tried setting has_add_permission=False within the two models, but it would make it impossibile to add new objects to such models completely, not only in this form.

How can I do that?

EDIT: To clarify my need, I'd like NOT to have the "+"s next to the fields of the FK models, but I do still want to be able to add whole new inlines. To be as clear as possible, as I wrote in a comment, considering a scenario such as this: https://code.djangoproject.com/attachment/ticket/20367/django_custom_user_admin_form.png I just need to have the "+"s next to Groups and Country removed.

EXISTING CODE:

models.py (of the specific application involved):

from django.db import models

from smart_selects.db_fields import ChainedForeignKey

from apps.comune.models import Comune, Cap


class Prodotto(models.Model):
    SETTORE_CHOICES = (
        ('CAL', 'Accessori calzature'),
        ('ALI', 'Alimentari'),
        ('ARA', 'Arredamenti e accessori'),
        ('AEM', 'Auto e moto'),
        ('CAL', 'Calzature'),
        ('CEG', 'Cartaria e grafica'),
        ('CEP', 'Concerie e pelletterie'),
        ('EDI', 'Edilizia'),
        ('INV', 'Industrie varie'),
        ('IST', 'Istruzione'),
        ('MDC', 'Materiali da costruzione'),
        ('MMC', 'Metalmeccanica'),
        ('SEI', 'Serramenti e infissi'),
        ('STM', 'Strumenti musicali'),
        ('TEI', 'Terziario innovativo'),
        ('TAB', 'Tessile abbigliamento'),
        ('TCP', 'Trasporto cose e persone'),
        ('VAR', 'Vari'),
    )
    nome = models.CharField(max_length=100)
    settore = models.CharField(max_length=40, choices=SETTORE_CHOICES)

    class Meta:
        verbose_name_plural = "prodotti"
        verbose_name = "prodotto"
        ordering = ['nome']

    def __unicode__(self):
        return self.nome.capitalize()


class Cliente(models.Model):
    TIPOLOGIA_CHOICES = (
        ('AR', 'Artigiano'),
        ('CO', 'Commerciante'),
        ('GI', 'Grande impresa'),
        ('PI', 'Piccola impresa'),
    )
    FORMA_SOCIETARIA_CHOICES = (
        ('SNC', 'S.n.c.'),
        ('SRL', 'S.r.l.'),
        ('SPA', 'S.p.A.'),
        ('SAS', 'S.a.s.'),
        ('COOP', 'Coop.A.r.l.'),
        ('DI', 'D.I.'),
        ('SCARL', 'S.c.a.r.l.'),
        ('SCPA', 'S.c.p.a.'),
    )
    SETTORE_CHOICES = (
        ('CAL', 'Accessori calzature'),
        ('ALI', 'Alimentari'),
        ('ARA', 'Arredamenti e accessori'),
        ('AEM', 'Auto e moto'),
        ('CAL', 'Calzature'),
        ('CEG', 'Cartaria e grafica'),
        ('CEP', 'Concerie e pelletterie'),
        ('EDI', 'Edilizia'),
        ('INV', 'Industrie varie'),
        ('IST', 'Istruzione'),
        ('MDC', 'Materiali da costruzione'),
        ('MMC', 'Metalmeccanica'),
        ('SEI', 'Serramenti e infissi'),
        ('STM', 'Strumenti musicali'),
        ('TEI', 'Terziario innovativo'),
        ('TAB', 'Tessile abbigliamento'),
        ('TCP', 'Trasporto cose e persone'),
        ('VAR', 'Vari'),
    )
    ragione_sociale = models.CharField(max_length=200)
    forma_societaria = models.CharField(
        max_length=5, choices=FORMA_SOCIETARIA_CHOICES)
    titolare = models.CharField(max_length=100, blank=True)
    partita_iva = models.CharField(
        max_length=11, verbose_name='Partita IVA', unique=True)
    tipologia = models.CharField(max_length=2, choices=TIPOLOGIA_CHOICES)
    settore = models.CharField(max_length=40, choices=SETTORE_CHOICES)
    prodotto = models.ManyToManyField(Prodotto, blank=True)

    class Meta:
        verbose_name_plural = "clienti"
        verbose_name = "cliente"

    def __unicode__(self):
        return self.ragione_sociale.capitalize()


class Sede(models.Model):
    nome = models.CharField(max_length=100)
    indirizzo = models.CharField(max_length=200, blank=True)
    cliente = models.ForeignKey(Cliente)
    comune = models.ForeignKey(Comune)
    cap = ChainedForeignKey(
        Cap,
        chained_field="comune",
        chained_model_field="comune",
        show_all=False,
        auto_choose=True,
    )

    class Meta:
        verbose_name_plural = "sedi"
        verbose_name = "sede"
        ordering = ['nome']

    def __unicode__(self):
        return self.nome.capitalize() + ", " + self.indirizzo

admin.py (of the specific application involved):

from django.contrib import admin

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


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
    list_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]


admin.site.register(Prodotto)

The admin interface of this app produces this:

Shortcut links 1 and 2 are the ones I need removed, being referred to columns (FKs) inside my inline classes. Shortcut links 3 and 4 are to be kept, since they refers to the inlines themselves.

解决方案

I think this is a less hacky solution than the one you ended up with. It worked for me, anyway.

Basically, it's the inline equivalent of what you suggested doing with the overriding the get_form method of ModelAdmin. Here we override get_formset in the inline class, get the form off the formset, and do the exact same thing. Seems to work fine, at least in 1.9, which I am using.

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

这篇关于Django 1.7从内联形式移除添加按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆