Bootstrap

Django之自定义ModelForm的widget

之前写过ModelForm集成bootstrap,但是bootstrap的radio加上class="form-control"后就会显得很大,而且换行了,为了解决这个问题,就只有修改下radio widget RadioSelect。

ModelForm集成bootstrap: https://blog.csdn.net/tang05709/article/details/104426312

修改radio其实很简单的,首先看看源码:django/forms/widgets.py

https://github.com/django/django/blob/master/django/forms/widgets.py

大概757行,是RaioSelect,很短很简单。

首先我们建立widgets文件夹,并建立自己的widget,如MyWidget,然后把RadioSelect拷贝一下,做如下修改。

from django.forms.widgets import RadioSelect

class TyRadioSelect(RadioSelect):
    template_name = '../templates/widgets/radio.html'
    option_template_name = '../templates/widgets/radio_option.html'

在templates目录下新建目录widgets并新建文件radio.html和radio_option.html,然后根据自己的样式修改。

raido.html

{% with id=widget.attrs.id %}
<div class="customer-radio-group">
{% for group, options, index in widget.optgroups %}
    {% if group %}
        {{ group }}
    {% endif %}
    {% for option in options %}
        {% include option.template_name with widget=option %}
    {% endfor %}
    {% if group %}
  
    {% endif %}
{% endfor %}
{% endwith %}
</div>

radio_option.html

<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
<label>{{ widget.label }}</label>

使用

from .BaseForm import BootstrapModelForm
from django.forms import widgets as widget
from backend.widgets.TyWidgets import TyRadioSelect
from common.models import AdvPosition

class AdvPositionForm(BootstrapModelForm):
    class Meta:
        model = AdvPosition
        fields = ['name', 'status']
        widgets = {
            "status":TyRadioSelect(attrs={'class':'customer-form-radio'}),
        }  

到这里自定义就完了,但是看页面,radio还是很大,这是因为input还是有class="form-control".

那么就要想办法去掉,在ModelForm集成bootstrap: https://blog.csdn.net/tang05709/article/details/104426312这里,是怎么把class="form-control"加上去的,那么就可以在这里想办法去掉。

self.fields[field].widget.attrs这个是widget的所有属性,可以print打印一下,然后我们可以看到我们自定义的属性。

widgets = {
            "status":TyRadioSelect(attrs={'class':'customer-form-radio'}),
        }  

class="form-radio"

那么我们可以据此把radio排除掉。

def __init__(self, *args, **kwargs):
        super(BootstrapModelForm, self).__init__(*args, **kwargs)
        for field in iter(self.fields):
            if('class' in self.fields[field].widget.attrs):
                if(self.fields[field].widget.attrs['class'] == 'customer-form-radio'):
                    self.fields[field].widget.attrs.update({
                        'class': 'customer-form-radio'
                    })
            else:
                self.fields[field].widget.attrs.update({
                    'class': 'form-control'
                })

 

;