Reputation:
I need to create an inline formset which
a) excludes some fields from MyModel
being displayed altogether
b) displays some some fields MyModel
but prevents them from being editable.
I tried using the code below, using values()
in order to filter the query set to just those values I wanted returned. However, this failed.
Anybody with any idea?
class PointTransactionFormset(BaseInlineFormSet):
def get_queryset(self):
qs = super(PointTransactionFormset, self).get_queryset()
qs = qs.filter(description="promotion feedback")
qs = qs.values('description','points_type') # this does not work
return qs
class PointTransactionInline(admin.TabularInline):
model = PointTransaction
#formset = points_formset()
#formset = inlineformset_factory(UserProfile,PointTransaction)
formset = PointTransactionFormset
Upvotes: 10
Views: 11143
Reputation: 126731
Is this a formset for use in the admin? If so, just set "exclude = ['field1', 'field2']" on your InlineModelAdmin to exclude fields. To show some fields values uneditable, you'll have to create a simple custom widget whose render() method just returns the value, and then override the formfield_for_dbfield() method to assign your widget to the proper fields.
If this is not for the admin, but a formset for use elsewhere, then you should make the above customizations (exclude attribute in the Meta inner class, widget override in __init__ method) in a ModelForm subclass which you pass to the formset constructor. (If you're using Django 1.2 or later, you can just use readonly_fields instead).
I can update with code examples if you clarify which situation you're in (admin or not).
Upvotes: 6
Reputation: 943
One thing that doesn't seem to be said in the documentation is that you can include a form inside your parameters for model formsets. So, for instance, let's say you have a person modelform, you can use it in a model formset by doing this
PersonFormSet = inlineformset_factory(User, Person, form=PersonForm, extra=6)
This allows you to do all the form validation, excludes, etc on a modelform level and have the factory replicate it.
Upvotes: 12
Reputation: 69
I just had a similar issue (not for admin - for the user-facing site) and discovered you can pass the formset and fields you want displayed into inlineformset_factory
like this:
factory = inlineformset_factory(UserProfile, PointTransaction,
formset=PointTransactionFormset,
fields=('description','points_type'))
formset = factory(instance=user_profile, data=request.POST)
where user_profile
is a UserProfile
.
Be warned that this can cause validation problems if the underlying model has required fields that aren't included in the field list passed into inlineformset_factory
, but that's the case for any kind of form.
Upvotes: 2