Ответ 1
Вы можете изменить список self.fields
после вызова super
.
Я хочу исключить определенные поля в функции init формы модели в зависимости от переданного параметра, как это сделать? Я знаю, что могу добавлять поля exclude, используя мета-класс формы модели, но мне нужно, чтобы это было динамическим в зависимости от переданной переменной.
Спасибо
Вы можете изменить список self.fields
после вызова super
.
Вы должны использовать modelform_factory, чтобы создать форму "на лету" и передать в поля, которые вы хотите исключить.
def django.forms.models.modelform_factory (
model,
form = ModelForm,
fields = None,
exclude = None,
formfield_callback = lambda f: f.formfield()
)
Так что-то вроде
modelform_factory(MyModel, MyModelForm, exclude=('name',))
Вы должны использовать self._meta
вместо self.Meta
, потому что метод ModelForm.__new__
получает атрибуты формы self.Meta
и помещает их в self._meta
.
Связанный, чтобы исключить поля из подкласса, я расширил класс ModelForm следующим образом:
class ModelForm(djangoforms.ModelForm):
def __init__(self, *args, **kwargs):
super(ModelForm, self).__init__(*args, **kwargs)
meta = getattr(self, 'Meta', None)
exclude = getattr(meta, 'exclude', [])
for field_name in exclude:
if field_name in self.fields:
del self.fields[field_name]
Просто отметим: если ваша форма вызывается из класса ModelAdmin, просто создайте метод get_form для ModelAdmin:
def get_form(self, request, obj=None, **kwargs):
exclude = ()
if not request.user.is_superuser:
exclude += ('field1',)
if obj:
exclude += ('field2',)
self.exclude = exclude
return super(ProfessorAdmin, self).get_form(request, obj, **kwargs)
PS: измените ProfessorAdmin классом класса "владелец".
Я сделал вот так:
class Meta:
exclude = [field.label for field in Fields.objects.filter(visible=False)] + ['language', 'created_at']