tags:

views:

146

answers:

2

I am currently using inlineformset_factory to get a formset with Holidays for a Person, but I only want to display the Holiday objects that are in the future.

HolidaysFormset = inlineformset_factory(Person, Holiday)

Within the Person class, it is easy to get the future holidays:

def future_holidays(self):
    return self.holidays.filter(end__gte=datetime.date.today())

I have looked at the relevant source code, and the formfield_callback looked slightly promising, but that is only called on a per field basis, and cannot be used (I think) to limit which objects match.

Any suggestions? Will I be best off creating my own FormSet, or a sub-class of Holiday? Or should I be looking into using a custom Manager?

A: 

One solution is to provide a new FormSet Base class, with the .get_queryset() method overridden.

class BaseFutureHolidaysFormSet(BaseInlineFormSet):
    def get_queryset(self):
         return BaseInlineFormSet.get_queryset(self).filter(
                  finish__gte=datetime.date.today()
         )

Then use this in the factory method:

HolidaysFormSet = inlineformset_factory(Person, Holiday,
     formset=BaseFutureHolidaysFormSet)

This works, as intended.

(Oh, a thankyou to The Nested Float, as this type of solution is discussed there.)

Matthew Schinckel
A: 

This solution did not work for me - I only got strange error messages.

My solution in Django 1.1 (in my application, not in admin app) was to go back to basic model FormSet, which has support for limiting queryset: http://docs.djangoproject.com/en/1.1/topics/forms/modelforms/#changing-the-queryset.

For example:

MyFormSet = modelformset_factory(MyModel)

and

myformset = MyFormSet(queryset=MyModel.objects.exclude(..criteria here..).filter(document=object_id))

I also tried multiple ways of over riding BaseInlineFormset class, but none worked.

Although this works, in my project simplifying the model might be a better solution.

h-kippo
What sort of errors?
Matthew Schinckel