Reputation: 1684
Assume we have a custom user model in a Django application. In order to make it CRUDable from the admin page, we want to define some forms.
Below is the UserChangeForm
used to modify an instance of our custom user model
class UserChangeForm(forms.ModelForm):
class Meta:
model = MyCustomUser
fields = (
...,
'email',
'is_active',
'is_admin',
'groups',
....
)
The question is: how do I implement a conditional fields
in the Meta
class based on the model instance (i.e., out of scope for Meta)?
The goal is to declare something like
def get_fields(self):
if self.instance.is_company:
return ('email', 'company_name', 'headquarters')
else:
return ('email', 'first_name', 'last_name')
in the outer class, then find a way to inject the result of the function in Meta.fields
. Any idea?
Upvotes: 1
Views: 1105
Reputation: 308899
If you're using the Django admin, you can use the ModelAdmin.get_fields
method.
class UserModelAdmin(admin.ModelAdmin):
...
def get_fields(request, obj=None):
if obj is None:
return ('email', ...) # suitable list of fields for adding object
elif obj.is_company:
return ('email', 'company_name', 'headquarters')
else:
return ('email', 'first_name', 'last_name')
Upvotes: 2
Reputation: 45575
You can delete fields from the form in the __init__()
constructor:
class UserChangeForm(forms.ModelForm):
class Meta:
fields = ('email', 'company_name', 'headquarters',
'first_name', 'last_name', )
def __init__(self, *args, **kwargs):
super(UserChangeForm, self).__init__(*args, **kwargs)
if self.instance.is_company:
fields_to_delete = ('first_name', 'last_name')
else:
fields_to_delete = ('company_name', 'headquarters')
for field in fields_to_delete:
del self.fields[field]
Upvotes: 6