【问题标题】:Overriding Size of Django Admin Multi-select Widget覆盖 Django Admin 多选小部件的大小
【发布时间】:2012-09-02 01:35:44
【问题描述】:

新手 Django 问题:我希望 Django 管理员在多选小部件中显示更多行选择。我有一个非常长的列表可供选择,默认的 4 行并不方便,尤其是在滚动时。

现在,该小部件呈现为 select multiple,但我希望它是 select multiple size="12"。理想情况下,这应该针对特定字段,但我可以忍受所有字段都使用相同的大小属性呈现。

那么,在 Django 中,哪里是改变这一点的最佳位置呢?

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    我在 admin.py 中通过为所有 ManyToManyField 项设置总括大小来执行此操作,例如:

    from django.contrib import admin
    from django.forms import SelectMultiple
    from django.db import models
    from models import *
    
    class RiverAdmin(admin.ModelAdmin):
        formfield_overrides = { models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'10'})}, }
    
    admin.site.register(River, RiverAdmin)
    

    【讨论】:

    • 请注意,如果为RiverAdmin 中的相应字段设置了filter_horizontalfilter_vertical,这将不起作用。我花了一些时间来解决这个问题。
    【解决方案2】:

    如果您有一个会持续增长的长选择,我建议使用autocomplete widget

    无论如何,你可以:

    1. Create a ModelForm,用于相关模型

    2. Override the default widget,对于相关领域,

    3. Set widget's size attribute满足您的需求

    4. Enable that form in ModelAdmin,例如

      class YourModelForm(forms.ModelForm):
          class Meta:
              model = YourModel
              widgets = {
                  'your_field': forms.SelectMultiple(attrs={'size': 12})
              }
      
      
      class YourModelAdmin(admin.ModelAdmin):
          form = YourModelForm
      

    【讨论】:

    • 另外,需要在表单上设置'fields'属性或者'exclude'属性,否则django(3.2)会报错。
    【解决方案3】:

    有一个办法,就是重写formfield_for_manytomany来设置size属性。

    def formfield_for_manytomany(self, db_field, request, **kwargs):
            form_field = super().formfield_for_manytomany(db_field, request, **kwargs)
            if db_field.name in [*self.filter_horizontal]:
                form_field.widget.attrs={'size': '10'}
            return form_field
    

    【讨论】:

      【解决方案4】:

      我能够根据相关表行的初始数量来创建行数,但是它不会动态更新(可能需要将 Javascript 插入管理表单并通过 AJAX 查询行数,这太大而无法发布在这里)。

      class ProfileAdminForm(forms.ModelForm):
          class Meta:
              model = Profile
              fields = '__all__'
              widgets = {
                  # Will dynamically change number of rows in select multiple, however only after server reload.
                  'spec_profiles': forms.SelectMultiple(attrs={'size': SpecProfile.objects.count()})
              }
      
      class ProfileAdmin(admin.ModelAdmin):
          form = ProfileAdminForm
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-10
        • 2011-03-29
        • 2017-11-24
        • 1970-01-01
        • 2013-09-15
        • 2011-08-28
        • 2017-01-08
        • 2010-10-13
        相关资源
        最近更新 更多