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
show the 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 add_view
and change_view
.
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