Django: Initializing a FormSet of custom forms with instances
The trick is to use a "ModelFormset" instead of just a formset since they allow initialization with a queryset. The docs are here, what you do is provide a form=* when creating the model formset and queryset=* when your instantiating the formset. The form=* arguement is not well documented (had to dig around in the code a little to make sure it is actually there).
def edit(request): PointFormSet = modelformset_factory(Point, form = PointForm) qset = Point.objects.all() #or however your getting your Points to modify formset = PointFormset(queryset = qset) if request.method == 'POST': #deal with posting the data formset = PointFormset(request.POST) if formset.is_valid(): #if it is not valid then the "errors" will fall through and be returned formset.save() return #to your redirect context_dict = {'formset':formset, #other context info } return render_to_response('your_template.html', context_dict)
So the code walks through easily. If the request is a GET then the instantiated form is returned to the user. If the request is a POST and the form is not .is_valid()
then the errors "fall through" and are returned in the same template. If the request is a POST and the data is valid then the formset is saved.
Hope that helps.
-Will
If you only have one possible value which you want to set, or perhaps a closed of values, it is possible to set them after the user POSTS the data to your server using commit=False
Please consider the following code:
class UserReferralView(View): ReferralFormSet = modelformset_factory(ReferralCode, form=ReferralTokenForm, extra=1) def get(self, request): pass def post(self, request): referral_formset = UserUpdateView.ReferralFormSet(request.POST) if referral_formset.is_valid(): instances = referral_formset.save(commit=False) for instance in instances: instance.user = request.user instance.save() return redirect(reverse('referrals.success_view')) else: return redirect(reverse('referrals.failure_view'))