как изменить размер виджета django ManyToManyField на странице администратора

Я пытаюсь изменить размер от многих до многих полей Django 1.8 admin.

models.py

from django.db import models

class Material(models.Model):
    type = models.CharField(max_length=20, primary_key=True)
    def __unicode__(self):
        return self.type


class Pen(models.Model):
    label = models.CharField(max_length=20, blank=True, default='')
    materials = models.ManyToManyField(Material)

admin.py

from django.contrib import admin
from django.conf.urls import url
from .models import *
from django.forms import SelectMultiple

@admin.register(Pen)
class PenAdmin(admin.ModelAdmin):
    filter_horizontal = ('materials',)
    #formfield_overrides = { models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'5', 'width': '50px', 'style': 'width:50px'})}, }

    def get_form(self, request, obj=None, **kwargs):
        form = super(PenAdmin, self).get_form(request, obj, **kwargs)
        form.base_fields['materials'].widget.attrs['style'] = 'width: 70px;'
        return form

    class Media:
        js = ("js/resize_fields.js",)

@admin.register(Material)
class MaterialAdmin(admin.ModelAdmin):
    pass

resize_fields.js

document.onload = function() {
  document.getElementById("id_materials_to").style.width="70px";
};

как вы можете видеть, я попробовал 3 подхода:

1: Использование formfield_overrides. Это не имело никакого значения.

2: Загрузка javascript для изменения размера объекта html. Он запускается, но не изменяет его размер, потому что скрипт, похоже, запускается до виджета нагруженный.

3: Использование get_form. Как показано ниже, он изменяет размер только одного из полей выбора.

enter image description here

кто-нибудь знает, как изменить его размер по горизонтали?

обновление: Я обнаружил, что:

class PenAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.ManyToManyField: {'widget': SelectMultiple(attrs={'size':'5', 'style': 'color:blue;width:250px'})},

    }

будет работать, так как я удалил filter_horizontal, но я хочу использовать filter_horizontal! Если я не ошибаюсь, опция filter_horizontal будет использовать MultiWidget, который, по-видимому, не передает переопределение атрибутов суб-виджетов. Тем не менее, я думаю, что должно быть решение, где я могу запустить javascript после загрузки страницы. плз помогите

2 ответов


вы можете изменить размер виджета, переопределив стили CSS.

вам нужно будет переопределить следующие классы CSS:

  1. .selector - этот div содержит виджетов.

  2. .selctor-available - этот div содержит виджет слева.

  3. .selector-chosen - этот div содержит виджет справа.

сначала создайте файл CSS с именем resize-widget.css внутри справочник. Добавьте в файл следующий код:

.selector-available,
.selector-chosen {
    width: 200px;
}

.selector .selector-available input {
    width: 184px;
}

.selector select {
    width: 200px;
}

.selector {
    width: 450px;
}

в admin.py, поставьте этот файл CSS через class Media:

@admin.register(Pen)
class PenAdmin(admin.ModelAdmin):
    filter_horizontal = ('materials',)

    class Media:
        css = {
            'all': ('resize-widget.css',), # if you have saved this file in `static/css/` then the path must look like `('css/resize-widget.css',)`
        }

посетите админ. Виджет select должен выглядеть следующим образом:

enter image description here


я попробовал ответить xyres и обнаружил, что он работает, но некоторые правила CSS были переопределены другими правилами, которые использовали более конкретные селекторы.

чтобы исправить это, я изменил resize-widget.css следующим образом:

.form-horizontal .control-group .controls .selector {
    width: 100%;
}

.form-horizontal .control-group .controls .selector .selector-available,
.form-horizontal .control-group .controls .selector .selector-chosen {
    max-width: 45%;
}

.form-horizontal .control-group .controls .selector select {
    min-height: 200px;
}

эти правила не были переопределены и заставляли его работать на меня.