A curious problem came up while working on creating user accounts for a project. I needed to take in credit card information while creating a user but only wanted to display the payment token that I got back from stripe. The best way to do this was using two forms for a single model on the Django Admin.
Create The Model Forms
The first step is to create two forms, one for creating an Account and a second for editing an Account. This will generally
go in the
admin.py file located within the app you are working in.
class AccountChangeForm(ModelForm): class Meta: model = Account fields = ('email', 'first_name', 'last_name', 'phone', 'payment_token) class AccountCreateForm(ModelForm): card = CharField(initial=json.dumps(CARD, indent=4), widget=Textarea, required=True) class Meta: model = Account fields = ('email', 'first_name', 'last_name', 'phone', 'card_info')
Any model form you create wont have any effect until you set it within the appropriate ModelAdmin, in our case for the Account Model
class AccountAdmin(admin.ModelAdmin): ... form = AccountChangeForm
Set The Form You Want To Use In add_view And change_view
That solves the problem of only wanting to show the payment_token while editing the model but it won't
AccountChangeForm when trying to create an account. The best way to set a form depending on which action
you are taking in the model is though
class AccountAdmin(admin.ModelAdmin): ... def add_view(self, request, form_url='', extra_context=None): ... self.form = AccountCreateForm def change_view(self, request, object_id, form_url='', extra_context=None): ... self.form = AccountChangeForm